cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
kachveder
Level III

How to make a JMP script to make a new window for user input assigning values to a col based on another col

Hi there, 

 

I am stuck on a specific part of my JMP script and am hoping to get some help from a different set of eyes. 

 

I have a dataset that looks like this, but with a lot more categories, each with longer names. 

 

kachveder_1-1631903862033.png

I want to create another column, with numeric values, based on the given column. This product needs to be fully automated, with a pop-up window with each of the categories listed out, with number edit boxes that the user can input the numeric values that will correspond to a category. For example: 

 

Pop-up window box: new window with all prompts in the pop-up window box. 

Enter value corresponding to A: 

 

___1___

 

Enter value corresponding to B: 

 

___2___

 

Enter value corresponding to C:

 

___3___

 

Enter value corresponding to  

 

___4___ 

 

Enter value corresponding to E: 

 

___5___

 

 

The resulting data table should look like this: 

 

kachveder_2-1631904547962.png

 

Below is the JMP script that I have right now. I have also uploaded the JMP file to this post. What I need help with is in red text below. I am having trouble assigning the ith value in the for loop, based on user input and corresponding to the ith unique category in the list, unique_char, to the ith position in the initialized numeric list, num_list, which will be used later in the next for loop for creating the column 2 (at the end of the JMP script below). 

 

dt = Current Data Table();

//get the unique character variable list
Names Default To Here( 1 );
col9 = Column(dt, "Column 1");
unique_char = Associative Array(col9) << get keys; // unique_char = {"A", "B", "C", "D", "E"}

//get n items in character variable list
nuniquechar = N Items(unique_char); //will be 5, if categories are A, B, C, D, E

//initalize number list
num_list = {};

//create new window to create multiple number edit boxes
nw = New Window( "Set Values",
<<Modal,

// Make the for loop of for every item in nuniquechar list, 
// ask and save user input for the LSL in a element of the num_list list
	for (i = 1, 
		i <= nuniquechar, 
		i++,
		Text Box("Number for " || unique_char[i] || ":"),   //i.e. "Number for A:"
		
		// HELP: 
		// name a numeric variable on each iteration that will be the holder of a numeric edit box
		// put the resulting ith entry into the num_list
		num_list[i] = number edit box(), 
			// number box default is null/missing. If no input, place a missing value in the num_list
		
		
	)
	
);

// TO DO:
// Create new column assigning the num_list values to
// the corresponding rows based the unique character value.
// Pseudo-code:
// for(i in 1:nuniquechar)
// if :column 1 = unique_char[i], num_list[i]
//
//

The results from this will be the automated and user-friendly version of using the following conditional logic to make column 2 based on column 1's categories. 

 

kachveder_3-1631904996827.png

 

 

 

 

 

 

2 ACCEPTED SOLUTIONS

Accepted Solutions
jthi
Super User

Re: How to make a JMP script to make a new window for user input assigning values to a col based on another col

I'm using << Set Function with the number edit box to get the values to unique_aa associative array. Then using that associative array to build the formula column needed, after closing the modal window.

 

Names Default To Here(1);

dt = Current Data Table();

//get the unique character variable list
col9 = Column(dt, "Column 1");
unique_char = Associative Array(col9) << get keys;
nuniquechar = N Items(unique_char); //will be 5, if categories are A, B, C, D, E
unique_aa = Associative Array(unique_char, Repeat({.}, nuniquechar)); //repeat to initialize values as missing

//create new window to create multiple number edit boxes
vlbExpr = V List Box();
For(i = 1, i <= nuniquechar, i++,
	Insert Into(vlbExpr, Text Box("Number for " || Char(unique_char[i]) || ":"));   //i.e. "Number for A:"
	Eval(
		Eval Expr(Insert Into(vlbExpr, Number Edit Box(., <<Set Function(Function({this}, unique_aa[Expr(unique_char[i])] = this << get)))))
	);
);

nw = New Window("Set Values",
	<<Modal,
	vlbExpr,
	H List Box(
		Button Box("OK", 
		
		),
		Button Box("Cancel")
	)
);
//Show(unique_aa);

Eval(EvalExpr(dt << New Column("Column 2",
	Numeric,
	Continuous,
	<< Formula(
		Expr(unique_aa)[:Column 1]
	);
)));

 

For information about Eval(EvalExpr()) see Insert one expression into another using Eval Insert, Eval Expr, Parse, and Substitute . And if you want to have formula

-Jarmo

View solution in original post

ErraticAttack
Level VI

Re: How to make a JMP script to make a new window for user input assigning values to a col based on another col

Here is a little script that I put together -- not you may want an optional selector to make the new column numeric (here I just leave it as character).

 

You have to enter a new column name and there is a check to not run if the new name exists in the data table currently (I know JMP wont overwrite a column, but it can still be confusing).  

 

/* recode */

self = New Namespace();
Show( self << Get Name );

self:table = Current Data Table();
self:column = Insert( {}, self:table << Get Selected Columns );
self:column = self:column[1] << Get Name;
Show( self:column );
self:values = Associative Array( Column( self:table, self:column ) ) << Get Keys;

self:string list = {};
For( i = 1, i <= N Items( self:values ), i++,
	Insert Into( self:string list, Char( i ) )
);

Eval( Eval Expr(

win = New Window( "Set Values",
	<<Modal
,
	<<On Validate(
		self = Namespace( Expr( self << Get Name ) );
		return = 1;
		If( Glue( name = Trim( self:name box << Get Text ) ) == "",
			New Window( "Error",
				<<Modal,
				Text Box( "Please enter a name for the new column" )
			);
			return = 0;
		);
		If( return,
			lookup = Associative Array( self:values, self:recode box << Get );
			::__dunder_mifflin__ = lookup;
			names = self:table << Get Column Names( "String" );
			If( Contains( names, name ),
				New Window( "Error",
					<<Modal,
					Text Box( "Error, data table already contains column \!"" || name || "\!", please use a different name" )
				);
				return = 0;
			);
		);
		If( return,
			Eval( Parse( Eval Insert( JSL Quote(
				self:table << New Column( name, "Character", <<Set Each Value( ::__dunder_mifflin__[:Name("^self:column^")] ) )
			) ) ) );
		);
		return
	)
,
	<<On Close(
		self = Namespace( Expr( self << Get Name ) );
		self << Delete Namespace();
		1
	)
,
	self = Namespace( Expr( self << Get Name ) );
	V List Box(
		self:name box = Text Edit Box( "", <<Set Hint( "Column Name" ) )
	,
		Table Box(
			String Col Box( "Current",
				self:values
			)
		,
			self:recode box = String Col Edit Box( "Recode",
				self:string list
			)
		)
	)
)

) );

0;
Jordan

View solution in original post

4 REPLIES 4
jthi
Super User

Re: How to make a JMP script to make a new window for user input assigning values to a col based on another col

I'm using << Set Function with the number edit box to get the values to unique_aa associative array. Then using that associative array to build the formula column needed, after closing the modal window.

 

Names Default To Here(1);

dt = Current Data Table();

//get the unique character variable list
col9 = Column(dt, "Column 1");
unique_char = Associative Array(col9) << get keys;
nuniquechar = N Items(unique_char); //will be 5, if categories are A, B, C, D, E
unique_aa = Associative Array(unique_char, Repeat({.}, nuniquechar)); //repeat to initialize values as missing

//create new window to create multiple number edit boxes
vlbExpr = V List Box();
For(i = 1, i <= nuniquechar, i++,
	Insert Into(vlbExpr, Text Box("Number for " || Char(unique_char[i]) || ":"));   //i.e. "Number for A:"
	Eval(
		Eval Expr(Insert Into(vlbExpr, Number Edit Box(., <<Set Function(Function({this}, unique_aa[Expr(unique_char[i])] = this << get)))))
	);
);

nw = New Window("Set Values",
	<<Modal,
	vlbExpr,
	H List Box(
		Button Box("OK", 
		
		),
		Button Box("Cancel")
	)
);
//Show(unique_aa);

Eval(EvalExpr(dt << New Column("Column 2",
	Numeric,
	Continuous,
	<< Formula(
		Expr(unique_aa)[:Column 1]
	);
)));

 

For information about Eval(EvalExpr()) see Insert one expression into another using Eval Insert, Eval Expr, Parse, and Substitute . And if you want to have formula

-Jarmo
ErraticAttack
Level VI

Re: How to make a JMP script to make a new window for user input assigning values to a col based on another col

Here is a little script that I put together -- not you may want an optional selector to make the new column numeric (here I just leave it as character).

 

You have to enter a new column name and there is a check to not run if the new name exists in the data table currently (I know JMP wont overwrite a column, but it can still be confusing).  

 

/* recode */

self = New Namespace();
Show( self << Get Name );

self:table = Current Data Table();
self:column = Insert( {}, self:table << Get Selected Columns );
self:column = self:column[1] << Get Name;
Show( self:column );
self:values = Associative Array( Column( self:table, self:column ) ) << Get Keys;

self:string list = {};
For( i = 1, i <= N Items( self:values ), i++,
	Insert Into( self:string list, Char( i ) )
);

Eval( Eval Expr(

win = New Window( "Set Values",
	<<Modal
,
	<<On Validate(
		self = Namespace( Expr( self << Get Name ) );
		return = 1;
		If( Glue( name = Trim( self:name box << Get Text ) ) == "",
			New Window( "Error",
				<<Modal,
				Text Box( "Please enter a name for the new column" )
			);
			return = 0;
		);
		If( return,
			lookup = Associative Array( self:values, self:recode box << Get );
			::__dunder_mifflin__ = lookup;
			names = self:table << Get Column Names( "String" );
			If( Contains( names, name ),
				New Window( "Error",
					<<Modal,
					Text Box( "Error, data table already contains column \!"" || name || "\!", please use a different name" )
				);
				return = 0;
			);
		);
		If( return,
			Eval( Parse( Eval Insert( JSL Quote(
				self:table << New Column( name, "Character", <<Set Each Value( ::__dunder_mifflin__[:Name("^self:column^")] ) )
			) ) ) );
		);
		return
	)
,
	<<On Close(
		self = Namespace( Expr( self << Get Name ) );
		self << Delete Namespace();
		1
	)
,
	self = Namespace( Expr( self << Get Name ) );
	V List Box(
		self:name box = Text Edit Box( "", <<Set Hint( "Column Name" ) )
	,
		Table Box(
			String Col Box( "Current",
				self:values
			)
		,
			self:recode box = String Col Edit Box( "Recode",
				self:string list
			)
		)
	)
)

) );

0;
Jordan
pmroz
Super User

Re: How to make a JMP script to make a new window for user input assigning values to a col based on another col

Have you considered the Cols > Recode platform?  Might be a good low-tech way to do what you want.

kachveder
Level III

Re: How to make a JMP script to make a new window for user input assigning values to a col based on another col

For sure - that's something I thought about doing before I got stuck. But I want to have an application for people who don't know the JMP interface very well.