Bei der Lösung des Problems „Iterativ Spalten mit Formeln erstellen“ stieß ich auf die Notwendigkeit, die Lösung auf eine Weise zu strukturieren, deren Grund ich nicht verstehe. Meine anfängliche Lösung war
Names Default To Here( 1 );
dt =
// Open Data Table: semiconductor capability.jmp
// → Data Table( "semiconductor capability" )
Open( "$SAMPLE_DATA/semiconductor capability.jmp" );
colNames = dt << get column names( continuous, string );
For Each( {col}, colNames,
theTarget = (Column( Eval( col ) ) << get property( "Spec Limits" ))["Target"];
Eval(
Eval Expr(
New Column( col || " Minus Target",
Numeric,
"Continuous",
Format( "Best", 10 ),
Formula( As Column( Eval( col ) ) - Expr( theTarget ) )
)
)
);
);
Und es scheitert
Column NPN1 Minus Target Formula Interrupted
Name Unresolved: col at row 1 in access or evaluation of 'col' , col/*###*/
Formula evaluation errors have been ignored
Column NPN1 Minus Target Formula Interrupted
Name Unresolved: col at row 1001 in access or evaluation of 'col' , col/*###*/
Formula evaluation errors have been ignored
Durch das Erzwingen einer Zuweisung der Variablen col funktioniert der Code
Names Default To Here( 1 );
dt =
// Open Data Table: semiconductor capability.jmp
// → Data Table( "semiconductor capability" )
Open( "$SAMPLE_DATA/semiconductor capability.jmp" );
colNames = dt << get column names( continuous, string )<BR /><BR />For Each( {xcol}, colNames,
col = xcol;
theTarget = (Column( Eval( col ) ) << get property( "Spec Limits" ))["Target"];
Eval(
Eval Expr(
New Column( col || " Minus Target",
Numeric,
"Continuous",
Format( "Best", 10 ),
Formula( As Column( Eval( col ) ) - Expr( theTarget ) )
)
)
);
);
Sobald ich den Code ausführe mit
col = xcol;
Ich kann den Code ohne die Xcol-Zuweisung ausführen und der Originalcode wird funktionieren.
Das ist für mich verwirrend. Kann mir jemand den Grund dafür erklären?
Höchstwahrscheinlich muss jemand von JMP die richtige Antwort liefern. @EvanMcCorkle ?
Ich bin mir über den genauen Grund nicht im Klaren, aber ein Grund ist, dass die Spalte innerhalb der Formel nicht ausgewertet wird ( ändern Sie Eval() in Expr(), um den Spaltennamen in As Column() zu erzwingen) (Oder ich glaube, Sie können << Formeln nach der Formelerstellung ausführen und die Formel dann sofort entfernen, um sicherzustellen, dass sie nicht mit einer falschen Spalte erneut ausgewertet wird).
Wenn „col“ die Variable ist, die Sie für die einzelnen Containerwerte speichern, existiert sie mit diesen Werten nicht außerhalb der Schleife (indem Sie „xcol“ auf „col“ setzen, wird dies gewissermaßen umgangen).
Names Default To Here(1);
a = {"a", "b", "c"};
b = "z";
show(b);
For Each({b}, a,
show(b);
);
show(b);
/*
b = "z";
b = "a";
b = "b";
b = "c";
b = "z";
*/
Ich bevorzuge die Verwendung dieser Methode (Expr(NameExpr(AsColumn())), da hierdurch die Formel „sauberer“ bleibt (:name statt AsColumn("name")).
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/semiconductor capability.jmp");
colNames = (dt << get column names(continuous, string))[1::10];
For Each({col}, colNames,
theTarget = (Column(Eval(col)) << get property("Spec Limits"))["Target"];
Eval(
Eval Expr(
New Column(col || " Minus Target",
Numeric,
"Continuous",
Format("Best", 10),
Formula(Expr(NameExpr(As Column(col))) - Expr(theTarget))
)
)
);
);
Dies sind höchstwahrscheinlich nicht dieselben Probleme wie ... Each-Schleifen haben einen lokalen Gültigkeitsbereich mit der Funktion (das ist äußerst ärgerlich ... Each-Schleifen verhalten sich mit dem lokalen Gültigkeitsbereich der Funktion nicht richtig. Ich habe dies dem JMP-Support gemeldet)
Names Default To Here(1);
b = 2;
my_f = function({a}, {Default Local},
c = Transform Each({item}, a,
a * b
);
return(c);
);
my_f2 = function({a}, {Default Local},
b = b; // "Fix"
c = Transform Each({item}, a,
a * b
);
return(c);
);
Try(
show(my_f({1,2,3}));
,
show(exception_msg);
);
Try(
show(my_f2({1,2,3}));
,
show(exception_msg);
);