Hallo, ich habe die folgende Herausforderung, bei der ich Probleme beim Skripten habe.
Meine Startdatentabelle sieht wie folgt aus. Ich möchte Xi ausgehend von Spalte 2 = 0 als Kriterium rückwärts multiplizieren und die neuen Werte in eine neue Spalte einfügen.
Spalte1 Spalte2
X1 0
X2 y2
X3 y3
…
Xn yn
XX1 0
XX2 yy2
….
XXn jjn
….
….
Meine Enddatentabelle würde so aussehen:
Spalte1 Spalte2 Spalte3
X1 0 Xn*Xn-1*……X3*X2*X1
X2 y2 Xn*Xn-1*…..X3*X2
X3 y3 Xn*Xn-1*….*X3
…
Xn yn Xn
XX1 0 XXn*XXn-1*…..XX2*XX1
XX2 yy2 XXn*XXn-1*…..XX2
….
XXn jjn XXn
….
….
Kann mir bitte jemand helfen? Sehr geschätzt!
Die gewünschten Berechnungen lassen sich sehr einfach durchführen, wenn die Daten umgekehrt sind. Daher finden Sie hier ein kleines Skript, das die Werte anhand dieser Idee berechnet
names default to here(1);
// create the sample table
dt = New Table( "example",
Add Rows( 10 ),
New Column( "col1",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Values( [1, 2, 3, 2, 4, 5, 6, 7, 8, 9] ),
Set Display Width( 48 )
),
New Column( "col2",
Character( 1 ),
"Nominal",
Set Values( {"x", "x", "x", "y", "y", "y", "y", "z", "z", "z"} ),
Set Display Width( 45 )
)
);
// JSL to create the column you want
// create a new column to preserve the order of the data
dt << new column("origRow", formula(row()));
dt:origRow << delete formula;
// Reverse the order of the data
dt << sort(by(:origRow), order(descending), replace table(1));
// create the new column
dt << new column( "col3", formula(
If( Row() == 1, x = :col1 );
If( Lag( :col2 ) != :col2,
x = :col1,
x = x * :col1
);
x;
));
// Since the formula is dependent on the order of the data, the formula needs
// to be removed and the values set to static values
dt:col3 << delete formula;
// reorder the data table back to the original order and delete the origRow column
dt << sort(by(:origRow), order(ascending), replace table(1));
dt << delete columns(:origRow);
Und hier ist ein Teil von JSL, der die neue Spalte ohne Sortierung erstellt
Names Default To Here( 1 );
// create the sample table
dt = New Table( "example",
Add Rows( 10 ),
New Column( "col1",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Values( [1, 2, 3, 2, 4, 5, 6, 7, 8, 9] ),
Set Display Width( 48 )
),
New Column( "col2",
Character( 1 ),
"Nominal",
Set Values( {"x", "x", "x", "y", "y", "y", "y", "z", "z", "z"} ),
Set Display Width( 45 )
)
);
// create the new column
dt << New Column( "col3b" );
:col3b[N Rows( dt )] = :col1[N Rows( dt )];
For( i = N Rows( dt ) - 1, i >= 1, i--,
If( :col2[i + 1] != :col2[i],
:col3b[i] = :col1[i],
:col3b[i] = :col3b[i + 1] * :col1[i]
)
);
Hallo Jim @txnelson
Das funktionierte tatsächlich bei einer kleineren Tabelle (dh mehreren tausend Zeilen). Danke schön.
Das „neue“ Problem, das ich habe, ist, dass meine Datentabelle sehr groß ist. Als ich die Formel in die neue Spalte einbettete und auf „Übernehmen“ klickte, blieb das Programm hängen und ich musste jmp beenden, um herauszukommen.
Während ich mit der Maus über die Formel fahre, erscheint hier die Warnmeldung bezüglich der „aktuellen Datentabelle“.
„Current data table() hat Nebenwirkungen und ist normalerweise nicht für die Verwendung innerhalb einer Formel geeignet. Wenn dies erforderlich ist, können Sie expr oder eval verwenden, um die Ausführung in Formeln zu verhindern ......."
Meine Skriptfähigkeiten sind sehr begrenzt. Vielen Dank für Ihre weitere Hilfe zu diesem Thema!
Grüße,
Tinghui
@txnelson schrieb:
Hier ist die neue Formel. Es handelt sich um die gleiche Methode wie bei der letzten Formel, es müssen jedoch nur der Start- und Endpunkt für jede der Gruppen ermittelt werden.
If( Row() == 1,
curCol = :col2;
end = Max( Current Data Table() << get rows where( :col2 == curCol ) );
x = :col1;
,
:col2 != curCol;
curCol = :col2;
end = Max( Current Data Table() << get rows where( :col2 == curCol ) );
x = :col1;
);
For( i = Row() + 1, i <= end, i++,
x = x * :col1[i]
);
x;
Hier ist die neue Formel. Es handelt sich um die gleiche Methode wie bei der letzten Formel, es müssen jedoch nur der Start- und Endpunkt für jede der Gruppen ermittelt werden.
If( Row() == 1,
curCol = :col2;
end = Max( Current Data Table() << get rows where( :col2 == curCol ) );
x = :col1;
,
:col2 != curCol;
curCol = :col2;
end = Max( Current Data Table() << get rows where( :col2 == curCol ) );
x = :col1;
);
For( i = Row() + 1, i <= end, i++,
x = x * :col1[i]
);
x;

Hallo Jim @txnelson
Danke für deine Antwort.
Nein, meine Spaltennamen ändern sich nicht. Sie bleiben wie angegeben in Spalte 1 und Spalte 2.Ich möchte eine neue Spalte (col3) hinzufügen, die die Rückwärtsmultiplikation für denselben in col2 angegebenen Wert durchführt. In der folgenden Tabelle zeige ich meinen Bedarf.Kannst du bitte helfen?
Spalte1 Spalte2 Spalte3
1 x 6 (also 1 x 2 x 3)
2 x 6 (also 2 x 3)
3 x 3 (also 3)
2 Jahre 240 (also 2x4x5x6)
4 y 120 (also 4 x 5 x6)
5 und 30 (also 5 x 6)
6 und 6 (also 6)
7 z 504 (also 7x8x9)
8 z 72 (also 8x9)
9 z 9
Danke!
Ich habe meinen Beitrag entfernt, da mir die Gruppierungsvariable fehlte. Mein Ansatz würde in diesem Szenario nicht funktionieren.
Ich verstehe Ihre 3 Spaltensätze nicht.Es sieht so aus, als würden Sie Spaltennamen mitten in einer Datentabelle ändern, was in JMP nicht funktioniert.Stammt dieses Tabellenformat aus einer Excel-Tabelle?
Hier ist eine einfache Formel, die für eine Datentabelle wie folgt genau das tut, was Sie wollen

Die Datentabelle habe ich beigefügt.
Die verwendete Formel lautet:
x = :col2[Row()];
If( Row() < N Rows( Current Data Table() ),
For( i = Row() + 1, i <= N Rows( Current Data Table() ), i++,
x = x * :col2[i]
)
);
x;
Dieselbe Idee kann verwendet werden, wenn es mehrere Stellen in einer Datentabelle gibt, an denen die Multiplikation neu gestartet werden muss.Es müsste nur noch herausgefunden werden, wann ein Neustart und wann ein Ende erfolgen soll