Subscribe Bookmark RSS Feed

Quotes within expression

michielsjef

Community Trekker

Joined:

Feb 10, 2015

 

Suppose I want to concatenate a high number of tables that all have the same format. I would like to have one single call to concatenate function, rather than a loop to concatenate one data table at a time. This is because I want to learn expressions in JMP.

 

I would like to have something like this

 

Data table("dt1") << concatenate(data table("dt2"),data table("dt3"),…, data table("dt100"))

 
In this example, I’m creating copies of the same sample data, but imagine that they could come from different sources and contain different values.

 

close all(data tables, nosave);

dt1 = Open("$SAMPLE_DATA/Big Class.jmp");

N=100;

 

/*in this loop, I’m copying the data table and creating a string, with the aim to use it in the concatenate function*/

/*I’m using the escape character because I have double quotes*/

dt_string="";

for(i=2,i<=N,i++,

       dt_tmp = (dt1 << subset(all rows, all columns, invisible ));

       dt_name = "dt" || char(i);

       dt_tmp << set name(dt_name);

       if(dt_string=="",

                     dt_string = "data table(\!"" || dt_name || "\!")";,

                     dt_string = dt_string || ", data table(\!"" || dt_name || "\!")");

);

 

 

show(dt_string);

concat_expr = expr(dt1 << concatenate(dt_list));

show(concat_expr);

concat_expr2 = substitute(Nameexpr(concat_expr),expr(dt_list),dt_string);

show(concat_expr2);

eval(concat_expr2);

 

And my problem is that I have still the escape character in the expression and its evaluation fails.

Please could you propose a code to construct the correct expression?

Thanks in advance.

JF

 

 

4 REPLIES
ian_jmp

Staff

Joined:

Jun 23, 2011

Having read it twice, I think your 'concatenate' problem is just an example to allow you to dig into the use of expressions.

If not, though, please be aware that '<< Concatenate()' will take a list of tables, so you don't have to mess with them if you simply want to get the job done:

NamesDefaultToHere(1);

// Open a table

dt1 = Open("$SAMPLE_DATA/Big Class.jmp");

dt1script = dt1 << getScript;

// Make some copies

n = 4;

tbls = {};

For(i=1, i<=n, i++,

Eval(dt1script);

InsertInto(tbls, DataTable("Big Class "||Char(i+1)));

);

Show(tbls);

// Concatenate the copies to the first table - You can use the list of tables, tbls

dt1 << Concatenate(tbls, AppendToFirstTable);

// Close all but the first table

For(i=1, i<=NItems(tbls), i++, Close(tbls[i], NoSave));.

ms

Super User

Joined:

Jun 23, 2011

(Please, avoid posting code like close all(data tables, nosave); I was careless and could first not understand what had happened to all my open windows)


Looks like you get a mix of expressions and strings. At some stage the string must be parsed into executable code (preferably a list in this case).

Your code should work fine if you change the concat_expr2 assignment into this:

concat_expr2 = substitute(Nameexpr(concat_expr),expr(dt_list),parse("{"||dt_string||"}"));


However I suggest a simpler approach: skip the string and build a list directly.

dt1 = Open("$SAMPLE_DATA/Big Class.jmp");

N = 10;

dt_list = {};

For(i = 2, i <= N, i++,

    dt_tmp = dt1 << subset(all rows, all columns, invisible);

    Insert Into(dt_list, dt_tmp);

);

dt1 << concatenate(dt_list);

michielsjef

Community Trekker

Joined:

Feb 10, 2015

Thank you both for the answers. I was not aware that we can provide lists to concatenate functions.

The answer of MS was exactly what I was looking for. I was very close.

Below, I arrange the two options in order to compare the efficacy of the string vs the list.

The string option takes 2.85s and the list option takes 4.38s.

We can faster the code by doing the data table invisible. With the subset function, I can easily add the invisible option. But with the getscript, I do not know how to do it.

dt1 = Open("$SAMPLE_DATA/Big Class.jmp");

N=100;

begin=HP Time();

dt_string="";

for(i=2,i<=N,i++,

dt_tmp = (dt1 << subset(all rows, all columns ));

dt_name = "dt" || char(i);

dt_tmp << set name(dt_name);

if(dt_string=="",

dt_string = "data table(\!"" || dt_name || "\!")";,

dt_string = dt_string || ", data table(\!"" || dt_name || "\!")");

);

show(dt_string);

concat_expr = expr(dt1 << concatenate(dt_list));

show(concat_expr);

concat_expr2 = substitute(Nameexpr(concat_expr),expr(dt_list),parse("{"||dt_string||"}"));

show(concat_expr2);

eval(concat_expr2);

For(i=2, i<=N, i++, Close(data table("dt" || char(i)) , NoSave));

end=HP Time();

solution1=(end-begin)/1e6; /*to have seconds rather than microseconds*/

begin=HP Time();

dt1script = dt1 << getScript;

tbls = {};

For(i=2, i<=N, i++,

Eval(dt1script);

InsertInto(tbls, Data Table("Big Class "||Char(i)));

);

Show(tbls);

dt1 << Concatenate(tbls);

For(i=1, i<=NItems(tbls), i++, Close(tbls[i], NoSave));

end=HP Time();

solution2=(end-begin)/1e6; /*to have seconds rather than microseconds*/

ian_jmp

Staff

Joined:

Jun 23, 2011

To be clear, all the code I offered down to and including 'Show(tbls)' was just a quick way to make a list of tables you can feed to concatenate.

But if you want to make things invisible, you can do:

// Open a table

dt1 = Open("$SAMPLE_DATA/Big Class.jmp");

dt1script = dt1 << getScript;

Print(dt1script);

InsertInto(dt1script, Expr(Invisible));

Print(dt1script);


which, coincidentally, is a simple example of how you can manipulate expressions.