Si è verificato un problema quando ho provato a creare dinamicamente colonne formula. 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" venga 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 hanno problemi e test3 funziona bene (anche test4 e test5 sembrano funzionare bene, ma non sono sicuro che mi sentirei sicuro nell'usarli perché non ho idea del perché ottengano 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'aggiunta ().
Il parser vede le parentesi e imposta il file funzione flag sul nodo nell'albero delle espressioni. Senza genitori, il Col Mediano node è solo un nome che capita di avere figli che non verranno utilizzati (tranne che da arg() e char() conversione). 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 riconosciuta dal messaggio NewColumn. La gestione delle parole chiave prevede bambini, 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.