
Diese Demonstration zeigt einige Möglichkeiten zur Verwendung von Matrizen. Im Kursjournal klicke ich im Abschnitt „Aushärtezeitdaten“ auf „Aushärtezeitdaten“. Nehmen wir an, wir müssen die durchschnittliche Aushärtezeit für jedes Datum ermitteln. Dazu addieren wir alle Aushärtezeitwerte jeder Zeile und dividieren sie durch die Anzahl der Proben. Für diese Berechnung verwende ich Matrizen. Auch hier machen vektorisierte Operationen die Berechnung effizienter. Im Kursjournal habe ich ein vorgefertigtes Skript namens „Statistik mit Matrizen berechnen“. Ich verschiebe es, damit wir sowohl die Aushärtezeittabelle – wir machen sie etwas breiter, gleichmäßiger – als auch unser Skript sehen können. Das Skript erstellt zunächst eine Variable namens „s“. In „s“ wird das Ergebnis der J-Funktion gespeichert. Die J-Funktion erstellt eine Matrix mit einer bestimmten Anzahl von Zeilen, Spalten und einem Startwert. In diesem Fall verwende ich die Funktion „Nrow“ ohne Argumente. Es wird lediglich die Anzahl der Zeilen in der aktuellen Datentabelle geprüft. Ich führe die Zeile aus. Im Protokoll sehen Sie, dass in s nun dieser Spaltenvektor aus Nullen gespeichert ist. Damit füge ich die einzelnen Aushärtezeitwerte direkt hinzu. Ich verwende eine For-Schleife. Ich initialisiere c gleich, da ich mit den Aushärtezeitdaten mit der zweiten Spalte beginnen möchte. Ich prüfe, ob c kleiner oder gleich der Spaltenanzahl ist. Besonders bei größeren Datentabellen empfiehlt es sich, diese Zählung außerhalb der For-Schleifen durchzuführen, in einer Variable zu speichern und c mit dieser Variable zu vergleichen. Anschließend wertet der Parser den Hauptteil der For-Schleife aus. Betrachten wir zunächst die rechte Seite der Zuweisungsfunktion. Ich sende die Nachricht „get as matrix to column“ beim ersten Mal und füge sie direkt zu s hinzu. Anschließend aktualisieren wir c mit dem Post-Increment-Operator. Dadurch wird eine Eins direkt zu c hinzugefügt. Wir prüfen, ob c immer noch kleiner oder gleich der Anzahl der Spalten ist. Nun erhalten wir die Spalte als Matrix und addieren diese zu s. Ich führe nun die Zeilen durch. Beachten Sie, dass die Funktion for einen fehlenden Wert im Protokoll zurückgibt. Sie können jedoch mit der Maus über s fahren, um zu sehen, dass es nun diese recht großen Zahlen enthält: die Summe aller fünf Aushärtezeitspalten. Abschließend sende ich eine Nachricht an die aktuelle Datentabelle, die neue Spaltennachricht. Der Titel der neuen Spalte lautet „Durchschnitt“. Für die Werte – auch hier können dies feste Werte oder Werte sein – führe ich eine Berechnung durch. Ich kann also Funktionen an das Werteargument übergeben, ohne vorher Variablen erstellen zu müssen. Die Funktion hier – ich habe eine Divisions- und eine Subtraktionsfunktion – ist also … Ich nehme s, die Summe der Aushärtezeitspalten, und dividiere sie durch c minus. Das ergibt s durch c minus, da wir bei c mit dem Zählen begonnen haben. Das reduziert die Anzahl der addierten Elemente um eins. Natürlich musste c über den Test hinaus erhöht werden. Der Test musste fehlschlagen. Der endgültige Wert von c – ich kann mit der Maus darüberfahren und sehe, dass das ist. Trotzdem haben wir nur Elemente addiert. Deshalb dividieren wir durch c minus. Ich führe also diese letzte Zeile aus. Sie sehen, dass die Spalte „Durchschnitt“ in der Aushärtezeitdatentabelle erstellt wurde. Wie im Protokoll angegeben, habe ich eine Instanz eines Spaltenobjekts erstellt. Und tatsächlich könnte alles in der Zeile, dieses Ergebnis, einer Variablen zugewiesen werden, wenn ich mit dieser Spalte weiterarbeiten möchte. Im nächsten Schritt der Demonstration möchte ich nun mit allen Aushärtezeitdaten gleichzeitig arbeiten und Berechnungen durchführen. Ich extrahiere die gesamte Datentabelle als Matrix und nicht spaltenweise, wie in diesem vorgefertigten Skript. Zuvor möchte ich die gerade erstellte Spalte entfernen. Dazu wähle ich den gesamten Inhalt des Skript-Editors aus und sende eine Nachricht an die aktuelle Datentabelle: „Spalten löschen“. Die Spalte „Durchschnitt“ ist dabei besonders praktisch, wenn Sie Dinge testen oder etwas präsentieren. In einem Produktionsskript benötigen wir explizitere Tabellenreferenzen. Die aktuelle Datentabelle ist daher praktisch, wenn Sie mit Skripten üben und testen, wie etwas funktioniert. In der Praxis jedoch, wenn Sie ein Skript über verschiedene JMP-Versionen und in verschiedenen Situationen hinweg bereitstellen oder verwenden möchten, verwenden Sie diese explizite Datentabellenreferenz anstelle der aktuellen Datentabelle. Ich führe das Skript also aus. Dadurch wurde die Spalte gelöscht, die ich entfernen wollte. Diese skriptfähige Nachricht wurde an das Protokoll zurückgegeben. Nun lösche ich den Inhalt des Skript-Editor-Fensters. Ich extrahiere die gesamte Datentabelle als Matrix und speichere sie in der Variable m. m wird also das Ergebnis der an die aktuelle Datentabelle gesendeten Nachricht zugewiesen. Diese Nachricht lautet „get as matrix“. Ich führe das aus. Sie sehen im Protokoll (oder Sie können mit der Maus über m fahren), dass ich jetzt diese Matrix habe. Die erste Spalte enthält diese riesigen Zahlen. Das liegt natürlich daran, dass beim Senden von „get as matrix“ an eine Datentabelle generell alle numerischen Spalten extrahiert werden. Dazu gehören auch Datumsangaben. Der Tag hier wird als numerisch behandelt. Sie erkennen es am Symbol für den Modellierungstyp, da er fortlaufend ist. Der Datentyp muss numerisch sein. Sie können es auch erweitern – obwohl „day“ scheinbar Zeichen enthält, ist das nur Formatierung. Es ist also rechtsbündig, da es sich um eine Zahl handelt. „get as matrix“ extrahiert also auch diesen Wert. Wenn ich Berechnungen zur Aushärtezeit durchführen möchte – und tatsächlich geht es dabei um die Ermittlung eines Minimal- und Maximalwerts –, möchte ich diese großen Werte für den Tag in der Matrix nicht. Ich gehe also zu einer neuen Zeile. Dabei bin ich vorsichtig. Ich möchte den bereits vorhandenen Code im Fenster sichtbar halten, aber ich möchte nicht alles erneut ausführen. Deshalb führe ich immer nur eine Zeile nach der anderen aus. Um die erste Spalte zu entfernen, verwende ich die Variable m und indiziere sie mit einer Null und einer Eins. Wie Sie sich erinnern, bedeutet Indizieren lediglich, keine bestimmte Zeile auszuwählen. Mit anderen Worten: Ich weise alle Zeilen der ersten Spalte zu. Dieser weise ich die leere Matrix zu, die nur aus eckigen Klammern ohne Inhalt besteht. Um nur diese eine Zeile auszuführen, kann ich sie markieren und eine der Methoden verwenden, die wir zum Ausführen eines gesamten Skripts verwenden. Es wird jedoch nur der ausgewählte oder markierte Teil ausgeführt. Alternativ kann ich auf dem Ziffernblock einer Standard-Desktop-Tastatur die Eingabetaste ganz rechts verwenden. Das Protokoll enthält dann nur die leere Matrix. Wenn ich jetzt mit der Maus über m fahre oder m markiere und es ausführe, sehen Sie, dass wir nur noch Aushärtezeitwerte haben. Die erste Spalte mit den großen Datumszahlen ist entfernt. Ich gehe in eine neue Zeile und schaue mir einige der anderen Matrixfunktionen an, die wir verwenden können. Ich erstelle die Variable a, der das Ergebnis der Funktion loc, LOC, zugewiesen wird. Ich suche die Positionen in dieser Matrix m, an denen die Werte größer als sind. Wenn ich nur diese Zeile ausführe, behandeln wir die Matrix m wie einen Zeilenvektor. Wir zählen von der ersten Position aus und geben nur die Positionen, die einzelnen Indexpositionen, aller Elemente in der Matrix zurück, die größer als sind. Wenn ich nun die tatsächlichen Werte haben möchte, erstelle ich eine Variable namens avals. Ich signiere das Ergebnis der Indizierung der in m gespeicherten Matrix mit der Variable a. Ich führe diese Zeile aus. Die tatsächlichen Aushärtezeitwerte überschreiten. Um dieses Skript zu vereinfachen, hätte ich, wenn ich die Positionen all dieser Werte nicht speichern müsste, einfach die Matrix m mit der Funktion loc indizieren können. Ich benötige diesen zusätzlichen Schritt, die Positionen zu speichern und anschließend zu verwenden, es sei denn, ich habe einen anderen Grund, mit den Positionen zu arbeiten, die ich in diesem Beispiel ursprünglich in a gespeichert hatte. Als Nächstes berechne ich mit dieser Matrix einige transformierte Werte. Diese Transformation berechnet jede Beobachtung der Aushärtezeit abzüglich des Minimums über die gesamte Tabelle, dividiert durch den Bereich der maximalen bis minimalen Aushärtezeitwerte und multipliziert das Ergebnis mit . Das ist so, als würde man den Abstand jeder Beobachtung von der minimalen Aushärtezeit als Anteil des Bereichs nehmen. Dies verdeutlicht einen weiteren Vorteil der Arbeit mit Matrizen. Um einen Minimalwert für eine ganze Datentabelle zu finden, egal ob ich Skripte schreibe oder interaktiv arbeite, wären viele Schritte nötig, um die einzelnen Spalten der Tabelle zu finden. Bei einer Matrix hingegen reicht eine einzige Codezeile. In meinem Skript-Editor-Fenster – ich lösche jetzt den Inhalt – erstelle ich die Variable minCT (Min.-Aushärtezeit) und weise ihr das Ergebnis der min-Funktion mit m als Argument zu. Anschließend führe ich diese Zeile aus. Der Minimalwert ist: 1. Anschließend erstelle ich die Variable maxCT. Dieser weise ich das Ergebnis der max-Funktion mit m als Argument zu. Anschließend führe ich diese Zeile aus. Und jetzt kann ich diese Variablen für die Berechnung dieser Transformation verwenden. Ich erstelle die Variable t zum Speichern der Transformationswerte. Ich gehe in eine neue Zeile. t erhält also das Ergebnis von times, dann öffnende Klammern für den Zähler m minus minCT, schließende Klammern für das Divisionszeichen und dann öffnende Klammern für den Nenner, maxCT minus minCT. Ich kann also einfach diese Zeile ausführen und erhalte dann diese Transformationswerte. Jede Beobachtung minus dem Minimum als Anteil des Bereichs der Aushärtezeitwerte. Das sind jetzt viele Dezimalstellen. So genau sind wir wirklich nicht. Deshalb können wir diese Werte runden. Und ich gehe wieder in eine neue Zeile. Ich überschreibe die Werte in t, indem ich das Ergebnis der Rundungsfunktion wieder t zuweise. Sie könnten dies in einer neuen Variable tun, wenn Sie das Original beibehalten möchten. Aber ich tippe t und dann den Zuweisungsoperator, die Rundungsfunktion. Die Argumente sind zunächst: Was runde ich? Also, ich runde die in t gespeicherten Werte. Und dann: Wie viele Dezimalstellen brauche ich? Ich will Null. Dies kürzt die Werte in der Matrix. Das ist nicht dasselbe wie das Formatieren einer Datenspalte mit nur null Dezimalstellen, während die vollständigen Werte im Hintergrund gespeichert bleiben. Ich formatiere hier also nicht. Ich kürze die Werte. Ich führe das jetzt aus. Jetzt habe ich die Integer-Werte für die transformierten Werte. Um diese Werte wieder in die Datentabelle zur Aushärtezeit einzufügen, könnte man die Matrix durchlaufen und neue Spalten erstellen. Um eine komplett neue Datentabelle zu erstellen, gibt es eine sehr einfache Funktion namens „as table“. Es gibt optionale Argumente für die Benennung dieser Tabelle und der Spalten. Ich halte es für diese Demonstration einfach und verwende die Variable „t“ als Argument für „as table“. Wenn ich das ausführe, erhalte ich diese unbenannte Tabelle mit generischen Spaltennamen. Alle Werte aus der transformierten Matrix sind jedoch in dieser Tabelle enthalten. Auch hier könnte ich den Namen und die Spaltenüberschriften als Teil des Arguments „as table“ angeben. Oder ich könnte das Skript verwenden, um dies nachträglich zu ändern. Wir haben uns also verschiedene Möglichkeiten angesehen, numerische Werte aus einer Datentabelle zu extrahieren, entweder spaltenweise oder die gesamte Datentabelle, alle numerischen Spalten, die gesamte Datentabelle und einige Manipulationen, die wir mit Matrizen durchführen können.