Subscribe Bookmark RSS Feed

Repetition of phrases within the Fit Model platform - can it be avoided?

Hi - I'm often writing scripts that perform runs of the Fit Model platform on multiple input variables, for example as shown below:

dt = open("C:\Program Files\SAS\JMPPRO\11\Samples\Data\Airline Delays.jmp");

yVars = {"Elapsed Time", "Arrival Delay", "Distance"};

fmo = Fit Model(

       Y( eval(yVars) ),

       Effects( :Month ),

       Personality( Standard Least Squares ),

       Emphasis( Effect Leverage ),

       Run(

              yVars[1] << {Lack of Fit( 0 ), Plot Actual by Predicted( 0 ),

              Plot Regression( 0 ), Plot Residual by Predicted( 0 ),

              Plot Effect Leverage( 0 ), {:age<<

              {LSMeans Student's t(0.05, Crosstab Report( 0 ) )}}},

              yVars[2] << {Lack of Fit( 0 ), Plot Actual by Predicted( 0 ),

              Plot Regression( 0 ), Plot Residual by Predicted( 0 ),

              Plot Effect Leverage( 0 ), {:age <<

              {LSMeans Student's t(0.05, Crosstab Report( 0 ) )}}},

              yVars[3] << {Lack of Fit( 0 ), Plot Actual by Predicted( 0 ),

              Plot Regression( 0 ), Plot Residual by Predicted( 0 ),

              Plot Effect Leverage( 0 ), {:age <<

              {LSMeans Student's t(0.05, Crosstab Report( 0 ) )}}},

              )

       );

What I'd like to know is this: is there an easy way I can compact the various statements within the "Run" phrase into a single set of commands that will apply to all of the input variables?  In the above example I've only had to do this three times, but often I've got dozens of variables being processed.  I'd like to avoid the repetition of all the lack of fit, plot regression, leverage and letters reports etc if at all possible, not least because I could then make some of my function calls a lot more generic.  I've tried an assortment of list constructions and for loops within the Run( ) phrase but to no avail - but I could easily just not have hit on the correct syntax yet.

Many thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
Solution

You're on the right track. This variation of your approach seems to work (JMP 11):

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

:Age << set modeling type( Nominal );

yVars = {"Height", "Weight"};

// Set up the report options for each input variable in a "for" loop

my_Action_expr = Expr( run() );

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

  Insert Into(

  my_Action_expr,

  Eval Expr(

  Expr( yVars[i] ) << {Lack of Fit( 0 ), Plot Actual by Predicted( 0 ), Plot Regression( 0 ),

  Plot Residual by Predicted( 0 ), Plot Effect Leverage( 0 ), {Expr( yVars[i] ) <<

  {LSMeans Student's t( 0.05, Crosstab Report( 0 ) )}}}

  )

  )

);

// Standard Fit Model expression

fmo_expr = Expr(

  Fit Model(

  Y( Eval( yVars ) ),

  Effects( :Age ),

  Personality( Standard Least Squares ),

  Emphasis( Effect Leverage )

  )

);

// Insert options and run

fmo = Eval( Insert( Name Expr( fmo_expr ), Name Expr( my_Action_expr ) ) );

7 REPLIES
brady_brady

Staff

Joined:

Jun 9, 2012

One way to go about this is to define an expr_one() that does the following:

1) gets the current platform settings using Get Platform Preferences(), for example, oldprefs = Get Platform Preference(Fit least squares).

2) sets the platform preferences according to your wishes using the Set Platform Preferences() command.

Then define another expr_two() that sets the platform preferences back to their original values.

Then whenever you like, you can:

1) evaluate expr_one

2) run your generic fit model script

3) evaluate expr_two

Of course you could have many versions of expr_one to provide various combinations of options.

Cheers,

Brady

Thanks Brady - that's an extremely helpful suggestion which I can see several uses for in a lot of my scripts, as I've no idea how some of the users might have modified their preferences.  What I'll probably do in this instance is just make the entire Fit Model output invisible anyway and merely extract the bits I actually need for the analysis I'm assembling, so anyone running the script won't even be aware that I'm calling the platform.  I've looked through the list of preferences related specifically to the Fit Model platform though, and can't see one controlling the production of "letters reports" from the pairwise comparisons of treatments - and it's that aspect of the analysis that's my main problem here.  Please do correct me if I'm mistaken about that, as a preference that would generate that particular report by default would go a long way towards solving the problem.

Many thanks!

mpb

Super User

Joined:

Jun 23, 2011

The following script works on the Fitness data and might be a useful example for your script.

Ylist = {:Oxy, :Weight};

Fit Model(

    Y( eval(Ylist)),

    Effects( :Runtime ),

    Personality( Standard Least Squares ),

    Emphasis( Effect Leverage ),

    Run(

       

        Ylist << {Lack of Fit( 0 ), Plot Actual by Predicted( 1 ),

        Plot Residual by Predicted( 1 ), Plot Effect Leverage( 1 )}

    )

);

Many thanks MPB: that example of yours has actually raised more questions! As far as I can see from trying to modify it to get exactly what I need, it actually doesn't seem to work as intended: if I change all the plot settings from (1) to (0) to suppress them all then the plots still appear, suggesting to me that the script is ignoring the property changes and still using its default settings.

As a rather weird aside, I've now spotted that I made a mistake in my original example script which I'd have thought should have prevented the analysis from running at all - and yet the script still ran exactly as I intended. You'll see that in the original post I included three references to ":age" in the three letters summary reports that I requested - but these should have been "yVars[1]", "yVars[2]" and "yVars[3]" respectively. There was no ":age" variable in the data set - I forgot to change it from a previous attempt to get what I wanted using the Big Data sample data set. I'm now wondering if the variable name supplied here actually matters at all. Very strange.

Returning to the original problem, I've tried assembling my letters table options before running the Fit Model platform as shown below. This script doesn't actually work, but I imagine you can see what I'm trying to do here.  I'm trying first to create within a loop a list of display options for each input variable in turn, and then trying to apply your recommendations from an earlier thread (https://communities.sas.com/thread/52307) with some combination of eval, eval list, eval expr etc, to execute that list when running the platform.  Again however, I can't quite get the right syntax:

dt = open("$SAMPLE_DATA/Big Class.jmp");

:Age << set modeling type(Nominal);

yVars = {"Height", "Weight"};

// Set up the letter report options I want for each input variable in a "for" loop.  (the "i" looping variable will presumably need to be replaced by its actual value in these expressions, but I can't see how to do that);

my_Action_List = {};

for(i=1, i<=nItems(yVars), i++,

   insert into( my_Action_List, expr(yVars << {Lack of Fit( 0 ), Plot Actual by Predicted( 0 ), Plot Regression( 0 ), Plot Residual by Predicted( 0 ),

   Plot Effect Leverage( 0 ), {yVars << {LSMeans Student's t( 0.05, Crosstab Report( 0 ) )}}})

   )

);

// Then run all of them in one call of the Fit Model platform;

fmo = Fit Model( Y(Eval( yVars ) ),

Effects( :Age ),

Personality( Standard Least Squares ),

Emphasis( Effect Leverage ),

Run(eval list(my_Action_List))

);

Instinctively I feel I'm on the right track, but there are too many things I could get wrong to try all of them. Is this the wrong approach completely, or can something like this be made to work?

Many thanks for your input on this: it's really helpful.

mpb

Super User

Joined:

Jun 23, 2011

Again, shooting from the hip, for some situations this might work, namely choosing the Minimal Report emphasis. I see though that you probably are looking for a more flexible solution ...

Ylist = {:Oxy, :Weight};

Fit Model(

    Y( eval(Ylist)),

    Effects( :Runtime ),

    Personality( Standard Least Squares ),

    Emphasis( Minimal Report ),

    Run;

);

Solution

You're on the right track. This variation of your approach seems to work (JMP 11):

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

:Age << set modeling type( Nominal );

yVars = {"Height", "Weight"};

// Set up the report options for each input variable in a "for" loop

my_Action_expr = Expr( run() );

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

  Insert Into(

  my_Action_expr,

  Eval Expr(

  Expr( yVars[i] ) << {Lack of Fit( 0 ), Plot Actual by Predicted( 0 ), Plot Regression( 0 ),

  Plot Residual by Predicted( 0 ), Plot Effect Leverage( 0 ), {Expr( yVars[i] ) <<

  {LSMeans Student's t( 0.05, Crosstab Report( 0 ) )}}}

  )

  )

);

// Standard Fit Model expression

fmo_expr = Expr(

  Fit Model(

  Y( Eval( yVars ) ),

  Effects( :Age ),

  Personality( Standard Least Squares ),

  Emphasis( Effect Leverage )

  )

);

// Insert options and run

fmo = Eval( Insert( Name Expr( fmo_expr ), Name Expr( my_Action_expr ) ) );

This is exactly what I needed: bringing "Name Expr" along to the party is obviously key to handling this one, and I can see a host of other applications that I'd probably have previously assembled entirely as one big block of text which I'd then subsequently have parsed.

That's been phenomenally helpful - many thanks!