Die Indizierung einer Matrix (oder einer Liste) mit einer anderen Matrix (oder Liste) ist eine leistungsstarke Technik, um Skripte schnell und klein zu machen. Es gibt jedoch einen Grenzfall, den wir befürchten müssen und den wir für JMP 13 beheben. Vielleicht sollte ich „Reparatur“ in Anführungszeichen setzen, da jede Änderung eine potenzielle Störung darstellt, weshalb ich sie hier vor JMP 13 erläutern möchte.
Hier ist ein Beispiel für die Verwendung einer Matrix als Index in einer Datenspalte.
Open("$SAMPLE_DATA/Big Class.jmp");
tall rows = Loc(:height << Get Values() >= 67); // [25, 27, 30, 37, 39, 40]
:height[tall rows]; // [68, 69, 67, 68, 68, 70]
N Rows(:height[tall rows]); // 6
Wenn Sie mit diesem Programmierstil nicht vertraut sind, ist die zweite Zeile der Schlüssel. " :height << Werte abrufen() " gibt die Werte der Höhenspalte als Matrix zurück. Der Vergleich " >= 67 " gibt eine Matrix aus Nullen und Einsen zurück, die dem entspricht, wo der Ausdruck falsch (0) oder wahr (1) ist. Der Loc() Die Funktion gibt die Positionen der Einsen innerhalb der vorherigen Matrix zurück.
In diesem Fall erhalten wir [25, 27, 30, 37, 39, 40] als Zeilennummern, bei denen die Höhenspalte größer oder gleich 67 ist. Das ist an sich schon ziemlich praktisch, aber die wirkliche Stärke ergibt sich aus der Möglichkeit, diese Matrix als Index in einer Spalte oder einer anderen Matrix wie in der dritten und vierten Zeile zu verwenden.
Die Alternative zu dieser Technik wäre, eine For()-Schleife zu schreiben, um jede Zeile explizit zu durchlaufen. Natürlich durchläuft JMP in beiden Fällen immer noch die Zeilen, aber wenn es intern erfolgt, geht es viel schneller als in JSL. Und die JSL ist ohne die explizite Schleife kompakter.
Dasselbe können wir auch mit einer Matrixvariablen anstelle einer Datenspaltenreferenz machen:
m = :height << Get Values();
tall rows = Loc(m >= 67); // [25, 27, 30, 37, 39, 40]
m[tall rows]; // [68, 69, 67, 68, 68, 70]
N Rows(m[tall rows]); // 6
Bisher alles super. Schauen wir uns die gleichen Beispiele mit einem anderen Höhengrenzwert (70 statt 67) an:
tall rows = Loc(:height << Get Values() >= 70); // [40]
:height[tall rows]; // [70]
N Rows(:height[tall rows]); // 1
m = :height << Get Values();
tall rows = Loc(m >= 70); // [40]
m[tall rows]; // 70
N Rows(m[tall rows]); // error
Was schief gelaufen ist? Beachten Sie, dass data[tall rows] 70 statt [70] zurückgegeben hat. In vielen Fällen werden eine 1x1-Matrix und eine Zahl gleich behandelt, jedoch nicht immer. Die N Rows()-Funktion ist ein Beispiel dafür, wo sie einen Unterschied macht. Durch die Indizierung wird die 1x1-Matrix zu aggressiv in eine Zahl „vereinfacht“.
Eine Lösung besteht darin, anzurufen Ist Matrix() vor Gebrauch N Zeilen() . Eine andere Möglichkeit besteht darin, eine leere Matrix mit dem Ergebnis zu verketten, wodurch eine Matrix erstellt wird, unabhängig davon, ob die Quelle eine Zahl oder eine Matrix ist:
m = m |/ [];
In JMP 13 wird die 1x1-Matrix so beibehalten Das Ergebnis der Indexoperation ist immer dann eine Matrix, wenn der Index selbst eine Matrix ist . Das Gleiche gilt für die Listenindizierung und gilt bereits für die Datenspaltenindizierung.
Wir gehen davon aus, dass die Störung selten auftritt, da der Auslöser nicht häufig vorkommt und eine 1x1-Matrix und eine Zahl ohnehin oft gleich behandelt werden. Dennoch wird der JMP 13-Debugger die Möglichkeit haben, Stellen in Ihren Skripten zu identifizieren, die von der Änderung betroffen sein könnten.
Wenn Sie Feedback oder Bedenken haben, teilen Sie uns dies hier mit oder kontaktieren Sie uns danielvalente um zu sehen, ob Sie für das JMP 13 Early Adopter-Programm berechtigt sind, um die Änderung an Ihrem eigenen Code auszuprobieren.
Wie schalte ich die Unterbrechungswarnung dafür im Debugger aus?Ich muss immer wieder auf „Play“ klicken und es scheint, dass der Profiler nicht funktioniert.Es bleibt einfach hängen und ich kann nicht mehr auf Play drücken.
*EDIT* Egal.Ich habe die Option dafür gefunden.Danke
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Ich stimme zu, gut, eine einheitliche Indexierung zu haben.Mir gefällt die Tatsache, dass man leere Matrizen mit Formen erstellen kann.
Große Verbesserung. Hier ist ein weiterer Vorschlag für Matrizen: Vereinfachen Sie die Indizierung, wenn Sie eine Bedingung verwenden. Dies lässt sich am besten anhand eines Beispiels erklären. Nehmen wir an, ich habe eine Matrix, die ich finden und die Werte größer als 5 zurückgeben möchte:
mymatrix = [2,4,6,8,10];
newmatrix=mymatrix[loc(mymatrix>5)];
Vergleichen Sie dies mit ähnlichem Code in R:
mymatrix = matrix(cbind(2,4,6,8,10));
newmatrix=mymatrix[mymatrix>5];
OK, die erste Anweisung in R ist länger und die zweite Anweisung gibt einen Vektor statt einer Matrix zurück, aber die zweite Anweisung ist kürzer. Es wäre schön, wenn JMP in zukünftigen Versionen die einfachere Syntax in der zweiten Anweisung implementieren könnte.
Ich stimme zu, dass die neue Handhabung der Einzelwertmatrix eine Verbesserung darstellt, schließe mich aber auch der Forderung von Mark Bailey an, die verwirrende leere Matrixausgabe [](0,1) zu eliminieren. Das Ersetzen durch [] wäre für den Benutzer einfacher zu verstehen und zu handhaben. Normalerweise verwende ich Logik wie die folgende, um mit dieser Situation umzugehen:
dt=current data table();
rows_to_capture=dt<<GET rows="" where=""></GET>
Es unterscheidet zwischen verschiedenen leeren Matrizen mit einer Dimension ungleich Null; Manchmal ist die Form wichtig:
show(x00,nrows(x00),ncols(x00));
show(x10,nrows(x10),ncols(x10));
show(x01,nrows(x01),ncols(x01));
show(x11,nrows(x11),ncols(x11));
x00 = [];
N Rows(x00) = 0;
N Cols(x00) = 0;
x10 = [](1, 0);
N Rows(x10) = 1;
N Cols(x10) = 0;
x01 = [](0, 1);
N Rows(x01) = 0;
N Cols(x01) = 1;
x11 = [1];
N Rows(x11) = 1;
N Cols(x11) = 1;
Wir haben in unserem fortgeschrittenen Skriptkurs einen Fall, bei dem das Ergebnis eine leere Matrix ist, die tatsächlich zurückgegeben wird [](0,1) ..Diese Form scheint harmlos zu sein (das heißt, sie verhält sich wie eine einfache leere Matrix), erforderte jedoch immer eine Erklärung. Was bedeutet das (0,1) darstellen und wie würde es verwendet werden? Wenn es nichts darstellt oder keinen Zweck erfüllt, ziehen Sie bitte in Betracht, es zu entfernen.
Ich habe eine Menge Code vorhanden, der diese Ausnahme behandeln muss.Das ist definitiv eine Verbesserung.Vielen Dank für den Hinweis. Ich werde einen Blick darauf werfen, wie sich dies auf das aktuelle Codemuster auswirkt, das ich zur Bewältigung dieser Situation verwendet habe.