Ho riscontrato un problema quando ho provato a creare colonne formula in modo dinamico. Alla fine sono riuscito a risolverlo, ma vorrei sapere cosa sta succedendo qui. La mia ipotesi è che sia in qualche modo correlato al modo in cui sto costruendo la formula e che la "formula" viene valutata prima di essere impostata su colonna e quindi in qualche modo incasina la formula della colonna.
Ecco un esempio: le colonne create da test1 e test2 presentano problemi e test3 funziona correttamente (anche test4 e test5 sembrano funzionare bene, ma non sono sicuro che mi sentirei sicuro nell'usarle poiché non ho idea del motivo per cui ottengono convertito in riferimenti di colonna da stringhe)
Names Default To Here(1);
test1 = function({dt, val_col, by_cols}, {Default Local},
ref_list = Transform Each({col_name}, Insert(by_cols, val_col, 1),
Name Expr(As Column(dt, col_name));
);
new_col = Eval(Substitute(
Expr(dt << New Column("Formula", Numeric, Continuous,
Formula(_new_formula_)
)),
Expr(_new_formula_), Substitute(ref_list, Expr(list), Expr(Col Median))
));
return(new_col);
);
test2 = function({dt, val_col, by_cols}, {Default Local},
ref_list = Transform Each({col_name}, Insert(by_cols, val_col, 1),
Name Expr(As Column(dt, col_name));
);
new_formula = Substitute(ref_list, Expr(list), Expr(Col Median));
new_col = Eval(Substitute(
Expr(dt << New Column("Formula", Numeric, Continuous,
Formula(_new_formula_)
)),
Expr(_new_formula_), Name Expr(new_formula)
));
return(new_col);
);
test3 = function({dt, val_col, by_cols}, {Default Local},
ref_list = Transform Each({col_name}, Insert(by_cols, val_col, 1),
Name Expr(As Column(dt, col_name));
);
new_formula = Char(Substitute(ref_list, Expr(list), Expr(Col Median)));
new_col = Eval(Substitute(
Expr(dt << New Column("Formula", Numeric, Continuous,
Formula(_new_formula_)
)),
Expr(_new_formula_), Parse(new_formula)
));
return(new_col);
);
test4 = function({dt, val_col, by_cols}, {Default Local},
new_col = Eval(Substitute(
Expr(dt << New Column("Formula", Numeric, Continuous,
Formula(Col Median(_new_formula_))
)),
Expr(_new_formula_), Insert(by_cols, val_col, 1)
));
return(new_col);
);
test5 = function({dt, val_col, by_cols}, {Default Local},
new_col = Eval(Substitute(
Expr(dt << New Column("Formula", Numeric, Continuous,
Formula(_new_formula_)
)),
Expr(_new_formula_), Substitute(Insert(by_cols, val_col, 1), Expr(List), Expr(Col Median))
));
return(new_col);
);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
by_cols = {"age", "sex"};
val_col = "height";
col1 = test1(dt, val_col, by_cols);
col2 = test2(dt, val_col, by_cols);
col3 = test3(dt, val_col, by_cols);
col4 = test3(dt, val_col, by_cols);
col5 = test3(dt, val_col, by_cols);
Show(col1 << get formula);
Show(col2 << get formula);
Show(col3 << get formula);
Show(col4 << get formula);
Show(col5 << get formula);
//dt1 = dt << Subset(All Rows, Selected columns(0), Suppress formula evaluation(0));
//Close(dt, no save);
Se ad esempio apro l'editor di formule di Formula 2 e premo applica, potrei ricevere un errore

C'è un modo per recuperare dalle formule "rotte" e c'è la possibilità di vederlo durante la creazione che si romperà? Posso usare Parse(Char()) per ottenere una formula funzionante e posso anche creare un sottoinsieme di dati e le formule funzioneranno lì.
Testato con JMP Pro 16.2.0 su Windows 10.
tentativo
Expr(Col Median())
con l'extra ().
Il parser vede i genitori e imposta il funzione flag sul nodo nell'albero delle espressioni. Senza genitori, il Col Mediano node è solo un nome che ha figli che non verranno utilizzati (tranne per arg() e char() conversion ). In fase di esecuzione il nome non è nello spazio dei nomi delle variabili e lo spazio dei nomi delle funzioni integrate non verrà utilizzato, quindi il messaggio.
Penso che questa spiegazione sia coerente con il comportamento di tutti e 5 i test.
Formula (...) è diverso da ColMedian(...); ColMedian è una funzione JSL. Formula è una parola chiave che il messaggio NewColumn riconosce. La gestione delle parole chiave prevede figli, quindi potrebbe non aver bisogno di expr(Formula()), ma probabilmente funzionerebbe bene con esso.
modifica: sono abbastanza sicuro che il funzione flag non è esposto in JSL tramite arg(), ecc.