Utilisez expr() pour remplacer les noms de colonnes variables dans une formuleJ'essaie de créer des boucles imbriquées :
La 1ère boucle crée des colonnes et contient une formule
La 2ème boucle crée d'autres colonnes et la formule aura besoin des colonnes de la 1ère boucle
Ma question est dans la 2ème boucle, je n'arrive pas à configurer correctement les noms de colonnes dans la formule en utilisant 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
)
)
)
)
Automatisation et scriptsRe : Utiliser expr() pour remplacer les noms de colonnes variables dans une formuleCela pourrait donner une idée
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]
)
)
);
);
Modifier:
Si vous avez JMP16+, vous pouvez changer les boucles en For Each (cela utilise également Eval(EvalExpr()) au lieu de Eval(Substitute()) car à mon avis, c'est plus clair dans des cas simples comme celui-ci
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
)
))
));
);
);
Re : Utiliser expr() pour remplacer les noms de colonnes variables dans une formuleCela a résolu ma question, merci. Et la deuxième méthode semble encore plus claire
Encore une question, j'utilise blist[k] directement dans mon code, et vous utilisez "www" puis remplacez-le. Les deux donnent le même résultat calculé
Est-ce parce que ma méthode laissera une variable blist[k] dans la formule qui peut mal tourner si l'utilisateur essaie à nouveau d'appliquer la formule après l'exécution du code ?
Re : Utiliser expr() pour remplacer les noms de colonnes variables dans une formuleRéponse courte:
Oui. Si vous perdez la référence à blist ou k, la formule ne peut pas être réévaluée. Et si les formules sont réévaluées alors que vous avez toujours accès aux deux, même k sera utilisé pour toutes les formules qui donneraient des réponses incorrectes. Vous devriez pouvoir tester cela en exécutant dt << Réexécuter les formules ;
Voir plus...
Longue réponse:
Oui, si vous ne les évaluez pas, cela laissera blist[k] dans votre table de données. Ce serait alors la dernière valeur k que vous avez dans toutes les formules (problème si les formules sont réévaluées tout en ayant toujours accès à blist et k) et si la table est rouverte (ou pour une raison quelconque vous perdez l'accès à blist / k) ceux-là n'existeront pas du tout. Ces types de cas peuvent généralement être facilement vérifiés en vérifiant la formule


Un autre endroit où cela peut facilement se produire est celui des scripts graphiques et vous pouvez également les voir depuis la fenêtre de script graphique.</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)
);
Vous aurez deux scripts comme celui-ci

et il n'y aura pas de ligne sur Y = 60. De plus, si vous copiez le script du générateur de graphiques, il y aura une ligne au lieu de valeurs
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))}
)
)
)
et une solution simple à ce problème consiste à évaluer les valeurs
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))
);
));
De manière plus générale, je dirais que si vous commencez à remplacer les noms de variables en les évaluant par des valeurs, cela pourrait parfois être une bonne idée de tous les évaluer. Ce que je veux dire par là dans ce cas, c'est qu'il pourrait être avantageux d'évaluer également le titre de la colonne.
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
)
))
));
);
Cela présente par exemple un avantage supplémentaire lorsque vous déboguez votre code. Vous trouverez ci-dessous un exemple simple de création d'une colonne à partir d'une référence et avec une variable qui fonctionne correctement.
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)
));
));
mais si vous rencontrez des problèmes, vous pouvez simplement mettre en surbrillance EvalExpr() et tout ce qu'il contient et exécuter cette partie du script.

col_title n'est pas évalué (pas de problème dans ce cas MAIS cela pourrait l'être si vous aviez un script plus compliqué) et simplement en ajoutant (dans ce cas) un Expr() supplémentaire, vous obtiendrez plus d'informations sur ce qui se passe réellement

Re : Utiliser expr() pour remplacer les noms de colonnes variables dans une formuleMerci pour ces informations détaillées, et je peux comprendre votre point de vue, je vais modifier mon code comme exemple