Ich bin auf ein Problem gestoßen, als ich versucht habe, Formelspalten dynamisch zu erstellen. Ich habe es am Ende geschafft, es zu lösen, aber ich würde gerne wissen, was hier passiert. Meine Vermutung ist, dass es irgendwie damit zusammenhängt, wie ich die Formel aufbaue und dass die "Formel" ausgewertet wird, bevor sie auf Spalte gesetzt wird, und dann bringt sie irgendwie die Spaltenformel durcheinander.
Hier ist ein Beispiel: Spalten, die von test1 und test2 erstellt wurden, haben Probleme und test3 funktioniert gut (test4 und test5 scheinen auch gut zu funktionieren, aber ich bin mir nicht sicher, ob ich mich sicher fühlen würde, sie zu verwenden, da ich keine Ahnung habe, warum sie es tun aus Strings in Spaltenreferenzen umgewandelt)
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);
Wenn ich zum Beispiel den Formeleditor von Formula 2 öffne und auf Anwenden drücke, erhalte ich möglicherweise eine Fehlermeldung

Gibt es eine Möglichkeit, sich von den "kaputten" Formeln zu erholen, und besteht die Möglichkeit, während der Erstellung zu sehen, dass sie kaputt gehen? Ich kann Parse(Char()) verwenden, um eine Arbeitsformel zu erhalten, und ich kann auch eine Teilmenge der Daten erstellen, und die Formeln funktionieren dort.
Getestet mit JMP Pro 16.2.0 unter Windows 10.
Versuchen
Expr(Col Median())
mit dem Zusatz ().
Der Parser sieht die Klammern und setzt die Funktion Flag auf dem Knoten in der Ausdrucksbaumstruktur. Ohne Eltern, die Spalte Median node ist nur ein Name, der zufällig Kinder hat, die nicht verwendet werden (außer bei der Umwandlung von arg() und char()). Zur Laufzeit befindet sich der Name nicht im Namensraum von Variablen, und der Namensraum von eingebauten Funktionen wird nicht verwendet, daher die Meldung.
Ich denke, diese Erklärung stimmt mit dem Verhalten aller 5 Tests überein.
Formel (...) unterscheidet sich von ColMedian(...); ColMedian ist eine JSL-Funktion. Formel ist ein Schlüsselwort, das die NewColumn-Nachricht erkennt. Die Behandlung von Schlüsselwörtern erwartet Kinder, daher ist expr(Formula()) möglicherweise nicht erforderlich, würde aber wahrscheinlich gut damit funktionieren.
edit: Ich bin mir ziemlich sicher, dass die Funktion Flag wird in JSL nicht über arg() usw. verfügbar gemacht.