Subscribe Bookmark RSS Feed

Char() on an interaction effect

Highlighted
mjoner

Community Trekker

Joined:

Jun 23, 2011

I have a hard time believing this hasn't been asked before and must be searching the wrong keywords.

Background: I am assuming a user has run Fit Model and saved a result of interest as Script to the Data Table. I have written JSL to extract the Effects() argument from the saved script. Let's suppose we have Effects( :A, :B:, :A*:B).

I have already written JSL that gets this result (as long as I am NOT using Transform Column() in the model's effect list -- that would create a whole new can of worms):

testList = {:A, :B, :A*:B};

My Current Task: I want to write JSL to enable my user to select one of these three effects.

Current Status: What I have done so far is this:

win = New Window( "Test", Panel Box( "Choose an Effect", Radio Box( testList ) ) );

If I run this, I get a Radio Box with the effects "A", "B", and "Multiply". Clearly the Display Box is choosing to pull the Head() off the third effect, rather than simply showing "A*B".

Possible Solution: I think I could fix this by writing a loop to check Head(testList[i])=="Multiply()" and if it is, then code another loop to extract each of the Arg(testList[i], j), convert these to characters, put them in another list, and Concat Items() them with a "*" separator.

Question: Is there a more direct route than this that will give me a Radio Box with the effects "A", "B", and "A*B"?

1 ACCEPTED SOLUTION

Accepted Solutions
mjoner

Community Trekker

Joined:

Jun 23, 2011

Solution

Here is what I came up with. I decided to build a barebones Standard Least Squares, rather than substituting the Personality, since I don't know whether some of the Fit Model personalities might include messages that wouldn't work in Standard Least Squares.

 

script = (Current Data Table() << Get Property("Fit Model"));
scriptAsStandardLeastSquares = Expr(Fit Model());
nFitModelArgs = N Arg( script );
For( k = 1, k <= nFitModelArgs, k++,
	headString = Char( Head( Arg( script, k ) ) );
	If(
		headString == "Y" | headString == "Effects", Insert Into(scriptAsStandardLeastSquares, Arg(script, k))
	);
);
Insert Into(scriptAsStandardLeastSquares, Expr(Run()));
Insert Into(scriptAsStandardLeastSquares, Expr(Personality("Standard Least Squares")));
Insert Into(scriptAsStandardLeastSquares, Expr(invisible));
fm = Eval(scriptAsStandardLeastSquares);
effectList = (fm << Get Effect Names);
fm << Close Window;
9 REPLIES
David_Burnham

Super User

Joined:

Jul 13, 2011

Sometimes an indirect route is easier.  Since you have the script, run it in the background send the Get Effect Names to the fit model object, then you have the list that you can use for your radio buttons.

-Dave
mjoner

Community Trekker

Joined:

Jun 23, 2011

This is actually very promising for my application, but only works with the Fit Least Squares personality. Unfortunately, I need something that will work in Fit Least Squares but also with Fit Mixed and Generalized Regression.

mjoner

Community Trekker

Joined:

Jun 23, 2011

Although maybe I could simply re-write the Fit Model script to force the Standard Least Squares personality and run the (wrong) model just far enough to let me get at the Effect Names?

David_Burnham

Super User

Joined:

Jul 13, 2011

This is the sort of code I use:

// s = model script

// easier to manipulate strings
str = Char(NameExpr(s));		

// ensure there is a variable to store a reference to the model object
str = "mwin=" || str;


// run in the background SubstituteInto(str,"Fit Model(","Fit Model(Invisible,"); // change emphasis (could also change personality) pattern = "Emphasis(" + PatArb() + ")" + PatRem(); replace = "Emphasis( Minimal Report ), Run)"; Pat Match(strScript, pattern, replace); // execute and retrieve results Eval(Parse(str)); effects = mwin << Get Effect Names;
-Dave
txnelson

Super User

Joined:

Jun 22, 2012

I have solved this issue in the following way in the past

testList = {:A, :B, :A * :B};
newtestlist = testList;
For( i = 1, i <= N Items( testlist ), i++,
	newtestlist[i] = Char( testlist[i] )
);
win = New Window( "Test", Panel Box( "Choose an Effect", Radio Box( newtestList ) ) );
Jim
mjoner

Community Trekker

Joined:

Jun 23, 2011

This works but leaves the colons behind. Also this gets really ugly if the column names contain characters that force JMP to wrap the column name in the Name() function.

David_Burnham

Super User

Joined:

Jul 13, 2011

Once they are "chared" you can do a SubstituteInto to remove the colons

-Dave
mjoner

Community Trekker

Joined:

Jun 23, 2011

No, this won't work. Suppose I have a scientist who is deliberately using a colon in the column name (perhaps to represent a ratio). Then the JSL from @txnelson might look like this:

testList = {:Name("A:total"), :Name("B:total"), :Name("A:total") * :Name("B:total")};
newtestlist = testList;
For( i = 1, i <= N Items( testlist ), i++,
	newtestlist[i] = Substitute(Char( testlist[i] ), ":", "")
);
win = New Window( "Test", Panel Box( "Choose an Effect", Radio Box( newtestList ) ) );

The radio box then gives Atotal, Btotal, and the really ugly looking Name("Atotal") * Name("Btotal").

No, I think I'd prefer the Get Effect Names message as long as I can get it to work. I think I'm headed for rewriting the script saved to data table to force Standard Least Squares so I can get the names.

mjoner

Community Trekker

Joined:

Jun 23, 2011

Solution

Here is what I came up with. I decided to build a barebones Standard Least Squares, rather than substituting the Personality, since I don't know whether some of the Fit Model personalities might include messages that wouldn't work in Standard Least Squares.

 

script = (Current Data Table() << Get Property("Fit Model"));
scriptAsStandardLeastSquares = Expr(Fit Model());
nFitModelArgs = N Arg( script );
For( k = 1, k <= nFitModelArgs, k++,
	headString = Char( Head( Arg( script, k ) ) );
	If(
		headString == "Y" | headString == "Effects", Insert Into(scriptAsStandardLeastSquares, Arg(script, k))
	);
);
Insert Into(scriptAsStandardLeastSquares, Expr(Run()));
Insert Into(scriptAsStandardLeastSquares, Expr(Personality("Standard Least Squares")));
Insert Into(scriptAsStandardLeastSquares, Expr(invisible));
fm = Eval(scriptAsStandardLeastSquares);
effectList = (fm << Get Effect Names);
fm << Close Window;