Subscribe Bookmark RSS Feed

Error when making prompts

exj

Community Trekker

Joined:

Apr 18, 2012

I'm new with JMP, and I have found those nice examples about creating nice prompts in book "Jump into JMP scripting".

Still, I do not know how I create a simple prompt and make a subset with scripting based on those values what I select from that prompt.

Prompt should 'collect' values from a character column variable "yearm", for example I would like to make graph builder based on yearmonth valkues between [201007, 201012].

All comments are welcome. Thank you in advance for helping me out with this problem.

Error message: invalid subscript (must be number or list of numbers){1} in access or evaluation of 'Subscript' , quarter[select1 << get]

Here is some code:


Summarize( quarter= By( Column( dt, "yearm" ) ) );
nw = New Window( "Choose quarters",
hb = Panel Box( "Choose yearm",
select1 = List Box ( quarter,
dt << Select Where(
:yearm== quarter[select1 << get] );
selRows = dt << Get Selected Rows;
)
),
Button Box( "OK",
nw << Close Window;
dt << Select Where(
:yearm== quarter[select1 << get]
);
/* Selected rows are subsetted into new table. */
dt << Subset( Output Table Name( "Chosen quarters" ) );
)
);

1 ACCEPTED SOLUTION

Accepted Solutions
Solution

Yes, the Contains() function is more elegant here. But I get an error if selecting only one item in the above example. Probably because alist_num[select1 << get selected indices] then return a number instead of a list of numbers.

Here

dt << Select Where( contains(select1 << get selected, char(:age)) );

works better and should work regardless of :age being character or numeric.

10 REPLIES
pmroz

Super User

Joined:

Jun 23, 2011

I would not use quarter as a variable, as it is also a JMP function.  Maybe quarter_list?  Also try putting the close window statement last.  Untest code:

Summarize( quarter_list = By( Column( dt, "yearm" ) ) );

nw = New Window( "Choose quarters",

      hb = Panel Box( "Choose yearm",

            select1 = List Box(

                  quarter_list,

                  dt << Select Where( :yearm == quarter_list[select1 << get] );

                  selRows = dt << Get Selected Rows;

            )

      ),

      Button Box( "OK",

            dt << Select Where( :yearm == quarter_list[select1 << get] );

/* Selected rows are subsetted into new table. */

            dt << Subset( Output Table Name( "Chosen quarters" ) );

            nw << Close Window;

      )

);

exj

Community Trekker

Joined:

Apr 18, 2012

Thank you for your tips.

It still complains about those [select1 << get] points.

That variable yearm is a character variable and it didn't help even if I made yearm as a numeric variable.

"invalid subscript (must be number or list of numbers){1} in access or evaluation of 'Subscript' , quarter_list[select1 << get]"

ms

Super User

Joined:

Jun 23, 2011

What's inside square brackets when used as a list index must be a number (or list of numbers). Try instead

quarter_list[select1 << Get Selected Indices]

exj

Community Trekker

Joined:

Apr 18, 2012

Thank you, it works now fine when I select only one value of the variable, what should I do when I want to select for example three values of the variable to the new data with pressing Shitf?

ms

Super User

Joined:

Jun 23, 2011

The comparison

:yearm == quarter_list[select1 << get]

does not work for more than one value because it tests the equality of a cell value and a list. It will always return false (I don't think cells can contain lists).

There are several ways to do this. Here is one suggestion (for OK button script) where row selection is based on a matrix of row numbers obtained by looping through the list of selected items.

Button Box( "OK",

  rows = [];

  L = quarter_list[select1 << Get Selected Indices];

  For( i = 1, i <= N Items( L ), i++,

  rows = rows || (dt << get rows where( :yearm == L[i] ))

  );

/* Selected rows are subsetted into new table. */

  dt << Subset( Rows(rows), Output Table Name( "Chosen quarters" ) );

  nw << Close Window;

)

pmroz

Super User

Joined:

Jun 23, 2011

There's a convenient construct for searching a column using a list with the contains function.  The code below shows how to use it:

dt = open("$sample_data\big class.jmp");

Summarize( age_list = By( Column( dt, "age" ) ) );

alist_num = {};

for (i = 1, i <= nitems(age_list), i++,

    alist_num[i] = num(age_list[i]);

);

nw = New Window( "Choose ages",

    hb = Panel Box( "Choose ages",

        select1 = List Box(

            age_list,

            dt << Select Where( contains(alist_num[select1 << get selected indices], :age) );

            selRows = dt << Get Selected Rows;

        )

    ),

    Button Box( "OK",

        dt << Select Where( contains(alist_num[select1 << get selected indices], :age) );

/* Selected rows are subsetted into new table. */

        dt << Subset( Output Table Name( "Chosen ages" ) );

        nw << Close Window;

    )

);

Solution

Yes, the Contains() function is more elegant here. But I get an error if selecting only one item in the above example. Probably because alist_num[select1 << get selected indices] then return a number instead of a list of numbers.

Here

dt << Select Where( contains(select1 << get selected, char(:age)) );

works better and should work regardless of :age being character or numeric.

exj

Community Trekker

Joined:

Apr 18, 2012

Thank You Both for really good advices, I appreciate it! Code works now fine but it's a little bit slow when using 1.5million rows.

ms

Super User

Joined:

Jun 23, 2011

Ouch! Then Contains() will be painfully slow. I suggest using the built-in Data Filter() as part of the prompt. It will be much faster for large tables.

Try the example below in JMP 10 (seems not to work as is in JMP 9). Selection and subsetting is almost instantaneous for 1 million-row table (MacPro 8x2.8 GHz).

//Example table

dt = New Table( "Big",

  add rows( 1000000 ),

  New Column( "quarter", nominal, formula( 1 + 10 * Round( Random Uniform() / 3, 1 ) ) )

);

dt << runformulas();

Column( "quarter" ) << delete formula;

//Prompt

df = dt << datafilter( Columns( :quarter ) );

rdf = df << report;

rdf[Outline Box( 1 )] << set title( "Select one or more quarters" ) << append(

  Button Box( "Make Subset",

  dt << Subset( Output Table Name( "Chosen ages" ) );

  df << close, nw << close

  )

);

//optional costomization: rdf[listbox(4)]<<delete; rdf[listbox(11)]<<delete;