Provo a creare cicli nidificati:
Il primo ciclo crea alcune colonne e contiene una formula
Il 2° ciclo crea altre colonne e la formula avrà bisogno delle colonne del 1° ciclo
La mia domanda è nel 2° ciclo, non riesco a impostare correttamente i nomi delle colonne nella formula utilizzando eval() + substitue() + expr()
Names Default To Here( 1 );
dt = current data table();
a=3;
b=3;
alist = {1,2,3};
blist = {1,2,3};
// In actual script, above numbers will come from H list box input
For (i=1, i <= a, i++,
dt << New Column( eval("a_" || char(alist[i])), Formula(:gap*2) );
col = "a_" || char(alist[i]);
For (k=1, k <= b, k++,
eval(
substitute(
Expr(
dt << New Column( eval("a_" || char(alist[i]) || " b_" || char(blist[k])), Formula( If(:vvv > 0 & (:vvv < blist[k] ),1,0) ) );
),
Expr(vvv),
col //here gives wrong result, the formula doesn't really use column a_1, a_2, a_3, instead it use "a_1"......etc
)
)
)
)
Questo potrebbe dare qualche idea
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
a = 3;
b = 3;
alist = {1, 2, 3};
blist = {1, 2, 3};
// In actual script, above numbers will come from H list box input
For(i = 1, i <= a, i++,
new_col = dt << New Column(Eval("a_" || Char(alist[i])), Formula(:height* 2));
For(k = 1, k <= b, k++,
Eval(Substitute(
Expr(dt << New Column("a_" || char(new_col << get name) || " b_" || char(blist[k]),
Formula(If(vvv > 0 & (vvv < www), 1, 0))
)),
Expr(vvv), Name Expr(AsColumn(new_col)),
Expr(www), blist[k]
)
)
);
);
Modificare:
Se hai JMP16+ potresti cambiare i cicli in For Each (questo usa anche Eval(EvalExpr()) invece di Eval(Substitute()) poiché secondo me è più chiaro in casi semplici come questo
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
alist = {1, 2, 3};
blist = {1, 2, 3};
For Each({aval}, alist,
new_col = dt << New Column("a_" || Char(aval), Formula(:height * 2));
For Each({bval}, blist,
col_title = "a_" || Char(new_col << get name) || " b_" || Char(bval);
Eval(EvalExpr(
dt << New Column(col_title, Numeric, Nominal, Formula(
If(0 < Expr(Name Expr(As Column(dt, new_col))) < Expr(bval),
1
,
0
)
))
));
);
);
Questo ha risolto la mia domanda, grazie. E il secondo metodo sembra ancora più chiaro
Un'altra domanda, io uso blist[k] direttamente nel mio codice e tu usi "www" quindi lo sostituisci. Entrambi danno lo stesso risultato calcolato
È perché il mio metodo lascerà una variabile blist[k] nella formula che può andare storta se l'utente tenta di applicare nuovamente la formula dopo l'esecuzione del codice?
Risposta breve:
SÌ. Se si perde il riferimento a blist o k, la formula non può essere rivalutata. E se le formule vengono rivalutate mentre hai ancora accesso a entrambe, Stesso k verrà utilizzato per tutte quelle formule che darebbero risposte errate. Dovresti essere in grado di testarlo correndo dt << Riesegui le formule;
Visualizza altro...
Risposta lunga:
Sì, se non li valuti, lascerà blist[k] nella tua tabella dati. Questo sarebbe quindi l'ultimo valore k che hai in tutte le formule (problema se le formule vengono rivalutate pur avendo ancora accesso a blist e k) e se la tabella viene riaperta (o per qualche motivo perdi l'accesso a blist / k) quelli non esisteranno affatto. Questi tipi di casi possono solitamente essere facilmente verificati controllando la formula


un altro posto in cui ciò può accadere facilmente sono gli script grafici e puoi vederli allo stesso modo dalla finestra dello script grafico</CODE></P>
<P> </P>
<PRE><CODE class=" language-jsl">Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Variables(X(:weight), Y(:height), Overlay(:sex)),
Elements(Points(X, Y, Legend(9)), Line Of Fit(X, Y, Legend(11)))
);
line = 60;
framebox = Report(gb)[frame box(1)];
framebox << Add Graphics Script(
H Line(line)
);
line = 70;
framebox << Add Graphics Script(
H Line(line)
);
Avrai due script come questo

e non ci sarà alcuna linea su Y = 60. Inoltre, se copi lo script del generatore di grafici, avrà una riga al posto dei valori
Graph Builder(
Variables(X(:weight), Y(:height), Overlay(:sex)),
Elements(Points(X, Y, Legend(9)), Line Of Fit(X, Y, Legend(11))),
SendToReport(
Dispatch(
{},
"Graph Builder",
FrameBox,
{Add Graphics Script(9, Description(""), H Line(line)),
Add Graphics Script(10, Description(""), H Line(line))}
)
)
)
e la soluzione semplice per questo è valutare i valori
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Variables(X(:weight), Y(:height), Overlay(:sex)),
Elements(Points(X, Y, Legend(9)), Line Of Fit(X, Y, Legend(11)))
);
line = 60;
framebox = Report(gb)[frame box(1)];
Eval(EvalExpr(
framebox << Add Graphics Script(
H Line(Expr(line))
);
));
line = 70;
Eval(EvalExpr(
framebox << Add Graphics Script(
H Line(Expr(line))
);
));
Più in generale, direi che se inizi a sostituire i nomi delle variabili valutandoli in valori, a volte potrebbe essere una buona idea valutarli tutti. Ciò che intendo in questo caso è che potrebbe essere utile valutare anche il titolo della colonna
Eval(EvalExpr(
dt << New Column(Expr(col_title), Numeric, Nominal, Formula(
If(0 < Expr(Name Expr(As Column(dt, new_col))) < Expr(bval),
1
,
0
)
))
));
);
Ciò presenta, ad esempio, ulteriori vantaggi durante il debug del codice. Di seguito è riportato un semplice esempio di creazione di una colonna dal riferimento e con una variabile che funziona correttamente
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
new_col = dt << New Column("Test", Numeric, Continuous, << Set Each Value(1));
col_title = (new_col << get name) || "* var";
var = 2;
Eval(EvalExpr(
dt << New Column(col_title, Numeric, Nominal, Formula(
Expr(NameExpr(AsColumn(dt, new_col))) * Expr(var)
));
));
ma se avessi qualche problema, potresti semplicemente evidenziare EvalExpr() e tutto ciò che contiene ed eseguire quella parte dello script

col_title non viene valutato (non è un problema in questo caso MA potrebbe esserlo se avessi uno script più complicato) e semplicemente aggiungendo (in questo caso) un'altra Expr() otterrai più informazioni su cosa sta realmente succedendo

Grazie per informazioni così dettagliate e posso capire il tuo punto, modificherò il mio codice come tuo esempio