Nel risolvere Crea iterativamente colonne contenenti formule mi sono imbattuto nella necessità di strutturare la soluzione in un modo di cui non capisco il motivo. La mia soluzione iniziale era
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 ) )
)
)
);
);
E fallisce
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
Mentre forzando un'assegnazione della variabile col il codice funzionerà
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 ) )
)
)
);
);
Inoltre, una volta eseguito il codice con
col = xcol;
Posso eseguire il codice senza l'assegnazione xcol e il codice originale funzionerà.
Questo mi confonde. Qualcuno può spiegare il ragionamento dietro questo?
Molto probabilmente qualcuno di JMP dovrà fornire la risposta corretta. @EvanMcCorkle ?
Non sono sicuro del motivo esatto, ma uno dei motivi è che la colonna non verrà valutata all'interno della formula ( cambia Eval() in Expr() per forzare il nome della colonna all'interno di As Column()) (Oppure penso che tu possa esegui << esegui le formule dopo la creazione della formula, quindi rimuovi immediatamente la formula per assicurarti che non venga rivalutata con una colonna errata).
Se col è la variabile che memorizzi per ciascun valore del contenitore, non esisterà al di fuori del ciclo con quei valori (l'impostazione di xcol su col lo ignora in qualche modo)
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";
*/
Preferisco utilizzare questo metodo (Expr(NameExpr(AsColumn())) poiché lascia la formula "più pulita" (:name invece di 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))
)
)
);
);
Molto probabilmente non si tratta degli stessi problemi di... Ogni loop ha l'ambito locale della funzione (questo è estremamente fastidioso... Ogni loop non si comporta correttamente con l'ambito locale della funzione. L'ho segnalato al supporto JMP)
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);
);