Ich versuche, Spaltenwerte für ausgewählte Zeilen in eine zusammengesetzte Beschriftung zu ziehen, die zum Kommentieren einer hinzugefügten Referenzzeile in einer Verteilung verwendet wird.
Die Fehlermeldung bei der Verkettung ist auf eine Nichtübereinstimmung der Listendimensionen zurückzuführen. Die zum Sammeln von Werten aus den ausgewählten Zeilen verwendeten assoziativen Array-Aufrufe entfernen doppelte Werte, was zu Listen mit eindeutigen Werten führt.
Mein Ziel besteht darin, den Namen, das Alter und das Gewicht für eine bestimmte ausgewählte Zeile in einer Zeichenfolge zu speichern, die in einem späteren Add-Ref-Aufruf als Bezeichnung verwendet werden kann.
Beim aktuellen Ansatz erhalte ich Fehlercodes und in manchen Fällen eine Fehlausrichtung der Daten ohne Fehlercode.
Beispiel 1 – Fehlerzustand: Es wurden drei eindeutige Gewichte gefunden, wobei die Listen für Alter und Namen jeweils nur zwei Elemente aus den ausgewählten Zeilen gefunden haben. Die dritte Iteration der Indizierung schlägt aufgrund der Unterschiede in den Listendimensionen fehl.
Beispiel 2 – Falsch ausgerichtete Daten: Es wurden drei Zeilen mit den Namen Leslie und Patty ausgewählt. Es gibt zwei Einträge mit dem Namen Patty, einer ist 14 Jahre alt und wiegt 85, der andere ist 16 Jahre alt und wiegt 134. Einer der Einträge für Patty und der Eintrag für Leslie sind beide 14 Jahre alt. Das Ergebnis falsch ausgerichteter Daten kann man sehen, wenn das Etikett nur die Listen für den Namen {"LESLIE", "PATTY"} und das Alter {14,16} berücksichtigt. Die Indizierung würde nur zwei Einträge ergeben, der erste ist "Leslie ...14", der zweite ist "Patty ...16", was eine korrekte Zuordnung ist, aber "Patty ...14" fehlt und die Listendimensionen sind datenabhängig.
Soll ich die assoziativen Array-Aufrufe entfernen und stattdessen zu einem Teilmengen-/Tabellenansatz wechseln oder soll ich die assoziativen Array-Aufrufe überarbeiten, um Listenelemente zu erhalten, bei denen es sich um Listen handelt, bei denen Name, Alter und Gewicht in jeder Iteration oder für jede ausgewählte Zeile erfasst werden?
Danke schön,
Bryan
Fehlercode bei Überschreiten der Listengröße:
Argument sollte ein Zeichen in Zeile 41 beim Zugriff oder bei der Auswertung von 'Concat' sein, Ungültiges Argument (theAges[i]), theNames[i] || /*###*/" ..." || /*###*/theAges[i] /*###*/

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
col_name_list = dt << get column names( string );
newColName = "State";
// New column: State
If( !Contains( col_name_list, newColName ),
Local( {dt, tempStrings},
dt = Data Table( "Big Class" );
dt << New Column( "State", Character, "Nominal" ) << Begin Data Update;
tempStrings = {"CA", "WA", "OR"};
For Each Row( dt, :State = tempStrings[Sequence( 1, 3, 1, 1 )] );
dt << End Data Update;
);
//Make it a double Patty :), another person with the same name.
dt << Add Rows( 1, At End );
//Cheat and use a constant of 41 for the last row index
dt[[41], {name, age, sex, height, weight, State}] = {{"PATTY", 16, "F", 57, 134, "WA"}};
);
// For illustration, select some names
dt << select where( Contains Item( :name, {"LESLIE", "PATTY"} ) );
dist = dt << Distribution(
Stack( 1 ),
Continuous Distribution(
Column( :height ),
Quantiles( 0 ),
Summary Statistics( 0 ),
Horizontal Layout( 1 ),
Normal Quantile Plot( 0 ), // disable, if the user enabled it in the preferences :)
Vertical( 0 ),
Set Bin Width( 2 ),
Process Capability( 0 )
//);
),
By( :State )
);
// get all reports
// if there is a BY group, get the info - if there is none, put it into a list
If( Is List( dist ),
dists=dist;
myBys = Transform each ({myexpr} , dist << Get Where Expr, Arg(myExpr , 2 ))
, //no By
dists = Eval List( {dist} );
myBys= {};
);
//get the reports
distRPTs = Transform Each( {dist}, dists, Report( dist ) );
// Find the Midpoints of the bins the selected rows are in
dist << Save( "Level Midpoints" );
//loop though the By groups and add the reflines
For Each( {report, idx}, distRPTs,
//report = distRPTs[2]; idx=2;
selected rows = dt << get selected rows;
// there is a BY group -> restrict the selection
if(N Items(myBys),
Eval( Eval Expr( selected rows = dt << get rows where( Contains( Expr( selected rows ), Row() ) & :State == Expr( myBys[idx] ) ) ) );
);
theBins = (Associative Array( Column( dt, N Cols( dt ) )[selected rows] )) << get keys;
theNames = (Associative Array( Column(dt, "name") [dt << get selected rows] )) << get keys;
theAges = (Associative Array( Column(dt, "age") [dt << get selected rows] )) << get keys;
theWeights = (Associative Array( Column(dt, "weight") [dt << get selected rows] )) << get keys;
For( i = 1, i <= N Items(theWeights), i++,
theLabels[i] = theNames[i] || " ..." || theAges[i] ;
);
);
dt << delete columns( N Cols( dt ) );Hallo Bryan, Sie könnten eine Transformationsspalte verwenden, um die richtigen Ergebnisse vorzubereiten – und dann die Einträge auswählen, die Sie benötigen:

Mehr anzeigen...Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
col_name_list = dt << get column names( string );
newColName = "State";
// New column: State
If( !Contains( col_name_list, newColName ),
Local( {dt, tempStrings},
dt = Data Table( "Big Class" );
dt << New Column( "State", Character, "Nominal" ) << Begin Data Update;
tempStrings = {"CA", "WA", "OR"};
For Each Row( dt, :State = tempStrings[Sequence( 1, 3, 1, 1 )] );
dt << End Data Update;
);
//Make it a double Patty :), another person with the same name.
dt << Add Rows( 1, At End );
//Cheat and use a constant of 41 for the last row index
dt[[41], {name, age, sex, height, weight, State}] = {{"PATTY", 16, "F", 57, 134, "WA"}};
);
// For illustration, select some names
dt << select where( Contains Item( :name, {"LESLIE", "PATTY"} ) );
dist = dt << Distribution(
Stack( 1 ),
Continuous Distribution(
Column( :height ),
Quantiles( 0 ),
Summary Statistics( 0 ),
Horizontal Layout( 1 ),
Normal Quantile Plot( 0 ), // disable, if the user enabled it in the preferences :)
Vertical( 0 ),
Set Bin Width( 2 ),
Process Capability( 0 )
//);
),
By( :State )
);
// get all reports
// if there is a BY group, get the info - if there is none, put it into a list
If( Is List( dist ),
dists=dist;
myBys = Transform each ({myexpr} , dist << Get Where Expr, Arg(myExpr , 2 ))
, //no By
dists = Eval List( {dist} );
myBys= {};
);
//get the reports
distRPTs = Transform Each( {dist}, dists, Report( dist ) );
// Find the Midpoints of the bins the selected rows are in
dist << Save( "Level Midpoints" );
dt << transform column ("label",Character, Formula (:name || " ..." || Char(age)));
//loop though the By groups and add the reflines
For Each( {report, idx}, distRPTs,
//report = distRPTs[2]; idx=2;
selected rows = dt << get selected rows;
// there is a BY group -> restrict the selection
if(N Items(myBys),
Eval( Eval Expr( selected rows = dt << get rows where( Contains( Expr( selected rows ), Row() ) & :State == Expr( myBys[idx] ) ) ) );
);
myLabels = Associative Array(:label[selected rows]) << get keys;
print(myLabels)
);
dt << delete columns( N Cols( dt ) );
Hallo @hogi
Ich habe Ihre Ideen in diesem Beitrag und dem zugehörigen Beitrag zum Hinzufügen einer Referenzzeile kombiniert.
Die Lösung zum Ausrichten der richtigen Informationen ohne Verlust wiederholter Werte und zum korrekten Hinzufügen von Behältern zu den Diagrammen im Stapel bestand darin, Listen aus den Feldern in der Tabelle vorzubereiten, indem ausgewählte Zeilen innerhalb einer verschachtelten For-Schleife indiziert wurden.
- Grundstücksverteilungen
- Sammeln nach Kriterien in einem Array für jedes Diagramm in einer Instanz im Bericht (3 Diagramme für jedes Datenelement, 3 Arrays)
- Sammeln Sie die Berichte in einem Objekt, das in der Iteration verwendet wird
- Die Mittelpunkte der dargestellten Daten anhängen (3 Diagramme, 3 Spalten an die Datentabelle anhängen)
- Durchlaufen Sie das Objekt mit einem „For Each“, um auf die einzelnen Diagramme zuzugreifen und sie zu erweitern.
- Listenvariablen für Behälter und Beschriftungen initialisieren
- Wählen Sie die Zeilen in den Daten basierend auf Basiskriterien aus (z. B. Seriennummer).
- Verfeinern Sie ausgewählte Zeilen anhand von Kriterien, die den Kriterien in den Diagrammen entsprechen.
- Verwenden Sie eine For-Schleife für so viele ausgewählte Zeilen
- Sammeln Sie die Behälter aus den angehängten Mittelpunktspalten (jedes Diagramm hat eine entsprechende Spalte).
- Sammeln Sie die Informationen aus den für Sie interessanten Spalten (z. B. Messdatum, Seriennummer) im Etikett.
- Referenzzeile mit gesammelten Informationen hinzufügen.
- Löschen Sie die Mittelpunktspalten, um veraltete Daten zu vermeiden, falls sich die Ploteinstellungen in Schritt 1 ändern.
Wichtige Änderungen, die geholfen haben:
1. Wechseln Sie vom assoziativen Array zu Listen, die durch Iteration gefüllt werden, um die Eliminierung doppelter Werte zu vermeiden und die Ausrichtung beizubehalten.
2. Erstellen Sie für jede der Bedingungen separate Variablen.
Ich hoffe, dies hilft, den Kreis zu schließen. Ich weiß Ihren Rat zu schätzen. Er hat mir das Lernen und den Fortschritt ermöglicht.