<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Use expr() to replace variable column names in a formula in Discussions</title>
    <link>https://community.jmp.com/t5/Discussions/Use-expr-to-replace-variable-column-names-in-a-formula/m-p/713851#M89730</link>
    <description>&lt;P&gt;I try to create nested loops:&lt;/P&gt;&lt;P&gt;1st loop create some columns and have formula with it&lt;/P&gt;&lt;P&gt;2nd loop create some other columns, and the formula will need columns from 1st loop&lt;/P&gt;&lt;P&gt;My question is in 2nd loop, I cannot correctly setup the column names in formula by using eval() + substitue() + expr()&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;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 &amp;lt;= a, i++, 
			dt &amp;lt;&amp;lt; New Column( eval("a_" || char(alist[i])), Formula(:gap*2) );
                        

	col = "a_" || char(alist[i]);

	For (k=1, k &amp;lt;= b, k++, 
			eval(
				substitute(
				Expr(
				dt &amp;lt;&amp;lt; New Column( eval("a_" || char(alist[i]) || " b_" || char(blist[k])), Formula( If(:vvv &amp;gt; 0 &amp;amp; (:vvv &amp;lt; 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
				)
			)
		)
	)&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Sat, 06 Jan 2024 17:46:49 GMT</pubDate>
    <dc:creator>BayesRabbit7133</dc:creator>
    <dc:date>2024-01-06T17:46:49Z</dc:date>
    <item>
      <title>Use expr() to replace variable column names in a formula</title>
      <link>https://community.jmp.com/t5/Discussions/Use-expr-to-replace-variable-column-names-in-a-formula/m-p/713851#M89730</link>
      <description>&lt;P&gt;I try to create nested loops:&lt;/P&gt;&lt;P&gt;1st loop create some columns and have formula with it&lt;/P&gt;&lt;P&gt;2nd loop create some other columns, and the formula will need columns from 1st loop&lt;/P&gt;&lt;P&gt;My question is in 2nd loop, I cannot correctly setup the column names in formula by using eval() + substitue() + expr()&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;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 &amp;lt;= a, i++, 
			dt &amp;lt;&amp;lt; New Column( eval("a_" || char(alist[i])), Formula(:gap*2) );
                        

	col = "a_" || char(alist[i]);

	For (k=1, k &amp;lt;= b, k++, 
			eval(
				substitute(
				Expr(
				dt &amp;lt;&amp;lt; New Column( eval("a_" || char(alist[i]) || " b_" || char(blist[k])), Formula( If(:vvv &amp;gt; 0 &amp;amp; (:vvv &amp;lt; 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
				)
			)
		)
	)&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 06 Jan 2024 17:46:49 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Use-expr-to-replace-variable-column-names-in-a-formula/m-p/713851#M89730</guid>
      <dc:creator>BayesRabbit7133</dc:creator>
      <dc:date>2024-01-06T17:46:49Z</dc:date>
    </item>
    <item>
      <title>Re: Use expr() to replace variable column names in a formula</title>
      <link>https://community.jmp.com/t5/Discussions/Use-expr-to-replace-variable-column-names-in-a-formula/m-p/713870#M89731</link>
      <description>&lt;P&gt;This might give some idea&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;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 &amp;lt;= a, i++,
	new_col = dt &amp;lt;&amp;lt; New Column(Eval("a_" || Char(alist[i])), Formula(:height* 2));
	
	For(k = 1, k &amp;lt;= b, k++,
		Eval(Substitute(
			Expr(dt &amp;lt;&amp;lt; New Column("a_" || char(new_col &amp;lt;&amp;lt; get name) || " b_" || char(blist[k]),
				Formula(If(vvv &amp;gt; 0 &amp;amp; (vvv &amp;lt; www), 1, 0))
			)),
			Expr(vvv), Name Expr(AsColumn(new_col)),
			Expr(www), blist[k]
			)
		)
	);
);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Edit:&lt;/P&gt;
&lt;P&gt;If you have JMP16+ you could change the loops to For Each (this also uses Eval(EvalExpr()) instead of Eval(Substitute()) as in my opinion it is more clear in simple cases like this&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;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 &amp;lt;&amp;lt; New Column("a_" || Char(aval), Formula(:height * 2));

	For Each({bval}, blist,
		col_title = "a_" || Char(new_col &amp;lt;&amp;lt; get name) || " b_" || Char(bval);
		
		Eval(EvalExpr(
			dt &amp;lt;&amp;lt; New Column(col_title, Numeric, Nominal, Formula(
				If(0 &amp;lt; Expr(Name Expr(As Column(dt, new_col))) &amp;lt;  Expr(bval),
					1
				,
					0
				)
			))
		));
	);
);

&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Sat, 06 Jan 2024 18:57:35 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Use-expr-to-replace-variable-column-names-in-a-formula/m-p/713870#M89731</guid>
      <dc:creator>jthi</dc:creator>
      <dc:date>2024-01-06T18:57:35Z</dc:date>
    </item>
    <item>
      <title>Re: Use expr() to replace variable column names in a formula</title>
      <link>https://community.jmp.com/t5/Discussions/Use-expr-to-replace-variable-column-names-in-a-formula/m-p/713902#M89736</link>
      <description>&lt;P&gt;This resolved my question, thank you. And the second method looks even more clear&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;One more question, I use blist[k] directly in my code, and you use "www" then replace it. Both give same calculated result&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Is it because my method will leave a variable&amp;nbsp; blist[k] in the formula that can go wrong if user try to apply formula again after the code has executed?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 07 Jan 2024 04:07:58 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Use-expr-to-replace-variable-column-names-in-a-formula/m-p/713902#M89736</guid>
      <dc:creator>BayesRabbit7133</dc:creator>
      <dc:date>2024-01-07T04:07:58Z</dc:date>
    </item>
    <item>
      <title>Re: Use expr() to replace variable column names in a formula</title>
      <link>https://community.jmp.com/t5/Discussions/Use-expr-to-replace-variable-column-names-in-a-formula/m-p/713926#M89737</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Short answer: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Yes. If you lose reference to either blist or k, formula cannot re-evaluate. And if formulas are re-evaluated while you still have access to both of those, &lt;STRONG&gt;same&lt;/STRONG&gt; k will be used for all of those formulas which would yield incorrect answers. You should be able to test this by running &lt;EM&gt;dt &amp;lt;&amp;lt; Rerun formulas;&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-SPOILER&gt;Working&lt;BR /&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");

alist = {1, 2, 3};
blist = {1, 120, 999};

For Each({aval}, alist,
	new_col = dt &amp;lt;&amp;lt; New Column("a_" || Char(aval), Formula(:height * 2));

	For Each({bval}, blist,
		col_title = "a_" || Char(new_col &amp;lt;&amp;lt; get name) || " b_" || Char(bval);
		
		Eval(EvalExpr(
			dt &amp;lt;&amp;lt; New Column(col_title, Numeric, Nominal, Formula(
				If(0 &amp;lt; Expr(Name Expr(As Column(dt, new_col))) &amp;lt;  Expr(bval),
					1
				,
					0
				)
			))
		));
	);
);

dt &amp;lt;&amp;lt; rerun formulas;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;BR /&gt;Possible issues (I changed to For loop as it is a bit easier to use for demonstration in this case)&lt;BR /&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");

alist = {1, 2, 3};
blist = {1, 120, 999};

For Each({aval}, alist,
	new_col = dt &amp;lt;&amp;lt; New Column("a_" || Char(aval), Formula(:height * 2));

	For(i = 1, i &amp;lt;= N Items(blist), i++,
		col_title = "a_" || Char(new_col &amp;lt;&amp;lt; get name) || " b_" || Char(blist[i]);
		
		Eval(EvalExpr(
			dt &amp;lt;&amp;lt; New Column(col_title, Numeric, Nominal, Formula(
				If(0 &amp;lt; Expr(Name Expr(As Column(dt, new_col))) &amp;lt;  blist[i],
					1
				,
					0
				)
			))
		));
	);
);
i = 3; // i would be 4 otherwise, so I set it to 3 for demo purposes
dt &amp;lt;&amp;lt; rerun formulas;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/LI-SPOILER&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Long answer:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Yes, if you don't evaluate them, it will leave blist[k] into your data table. This would then be last k value you have in all of the formulas (issue if formulas are re-evaluated while still having access to blist and k) and if the table is reopened (or for some reason you lose access to blist / k) those won't exist at all. These types of cases can be usually easily verified by checking the formula&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_0-1704613538642.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/60195i14122AE0BA4F4657/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_0-1704613538642.png" alt="jthi_0-1704613538642.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_1-1704613624458.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/60196i154B70A5EEC51C12/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_1-1704613624458.png" alt="jthi_1-1704613624458.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;other place where this can easily happen is graphic scripts and you can similarly see them from the graphic script window&lt;CODE class=" language-jsl"&gt;&lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here(1);

dt = open("$SAMPLE_DATA/Big Class.jmp");

gb = dt &amp;lt;&amp;lt; 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 &amp;lt;&amp;lt; Add Graphics Script(
	H Line(line)
);

line = 70;
framebox &amp;lt;&amp;lt; Add Graphics Script(
	H Line(line)
);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You will have two scripts like this&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_3-1704613921038.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/60198iCF2F62B3C74F5FE2/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_3-1704613921038.png" alt="jthi_3-1704613921038.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;and there will be no line on Y = 60. Also if you copy the graph builder script it will have line there instead of values&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;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))}
		)
	)
)&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;and easy fix for this is to evaluate the values&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here(1);

dt = open("$SAMPLE_DATA/Big Class.jmp");

gb = dt &amp;lt;&amp;lt; 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 &amp;lt;&amp;lt; Add Graphics Script(
		H Line(Expr(line))
	);
));

line = 70;
Eval(EvalExpr(
	framebox &amp;lt;&amp;lt; Add Graphics Script(
		H Line(Expr(line))
	);
));
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In more general, I would say that if you start replacing variable names by evaluating them to values, it might be a sometimes a good idea to evaluate all of them. What I mean by this in this case is that it might be beneficial to evaluate the column title also&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Eval(EvalExpr(
	dt &amp;lt;&amp;lt; New Column(Expr(col_title), Numeric, Nominal, Formula(
		If(0 &amp;lt; Expr(Name Expr(As Column(dt, new_col))) &amp;lt;  Expr(bval),
			1
		,
			0
		)
	))
));
);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This has for example additional benefit when you are debugging your code. Below is simple example of creating column from reference and with a variable which does work fine&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");

new_col = dt &amp;lt;&amp;lt; New Column("Test", Numeric, Continuous, &amp;lt;&amp;lt; Set Each Value(1));

col_title = (new_col &amp;lt;&amp;lt; get name) || "* var";
var = 2;

Eval(EvalExpr(
	dt &amp;lt;&amp;lt; New Column(col_title, Numeric, Nominal, Formula(
		Expr(NameExpr(AsColumn(dt, new_col))) * Expr(var)
	));
));&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;but if you had some issues, you could just highlight the EvalExpr() and everything inside it and run that part of the script&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_4-1704614319706.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/60199i5CA2BBC2BF84EA2F/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_4-1704614319706.png" alt="jthi_4-1704614319706.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;col_title isn't evaluated (not a problem in this case BUT it could be in if you had more complicated script) and just by adding (in this case) one more Expr() you will get more information what is really going on&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_5-1704614390307.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/60200i3DC3790E983977AE/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_5-1704614390307.png" alt="jthi_5-1704614390307.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 07 Jan 2024 08:18:24 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Use-expr-to-replace-variable-column-names-in-a-formula/m-p/713926#M89737</guid>
      <dc:creator>jthi</dc:creator>
      <dc:date>2024-01-07T08:18:24Z</dc:date>
    </item>
    <item>
      <title>Re: Use expr() to replace variable column names in a formula</title>
      <link>https://community.jmp.com/t5/Discussions/Use-expr-to-replace-variable-column-names-in-a-formula/m-p/713989#M89742</link>
      <description>&lt;P&gt;Thank you for such detailed information, and I can understand your point, I'll modified my code as your example&lt;/P&gt;</description>
      <pubDate>Mon, 08 Jan 2024 02:16:45 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Use-expr-to-replace-variable-column-names-in-a-formula/m-p/713989#M89742</guid>
      <dc:creator>BayesRabbit7133</dc:creator>
      <dc:date>2024-01-08T02:16:45Z</dc:date>
    </item>
  </channel>
</rss>

