cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar
pauldeen
Level VI

Parse a column formula and swap out parameters for column references

I'm writing a script that will allow users to select one of the fit models in Non-linear platform. Save the parameterized version out to the data table and then take the parameters and replace them with column references. So how to detect the parameters in the equation, change them and insert the whole thing back into the column as a formula.

 

In general I want to parse all arguments of a formula, detect when they are parameters, swap them out and reassemble the formula. I do not know upfront how many nested levels of arguments there are or how many parameters there will be.

 

Here is an example script of what I could do, with some comments and challenges:

Names Default To Here(1);

dttest = New Table( "Test table",
	Add Rows( 5 ),
	Compress File When Saved( 1 ),
	New Column( "Model",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Formula(
			Parameter( {a = 1, b = 2, c = 3}, a + b * :Tecta + c * :Tecta ^ 2 )
		)
	),
	New Column( "Tecta",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [1, 2, 3, 4, 5] )
	),
	New Column( "New a col ctttc",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [1, 1, 1, 1, 1] )
	),
	New Column( "New b col ctttc",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [2, 2, 2, 2, 2] )
	),
	New Column( "New c col atttc",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [3, 3, 3, 3, 3] )
	)
);

FormulaScript = column("Model") << get formula;
Parameters = arg(FormulaScript, 1);
Equation = arg(FormulaScript, 2);
NewParameters = remove(dttest << Get Column Names(string),1,n cols(dttest)-n items(Parameters));

StrictParameters = {};
for(i=1, i<=n items(Parameters), i++,
	insert into(StrictParameters,arg(Parameters[i],1));
);
	
ParameterSwap = Associative Array(StrictParameters, NewParameters);

//Step through all levels of equation to swap occurences of parameters with the corresponding index of NewParameters.
//Must be robust for no space before or after the parameters name.
//Must be robust for parameters being named "a" and be part of the name of a column.
//I tried using substitute but that will replace all instances of "a" with a column references and that does not go well.
//Tried using arg() but then you will have to traverse unknown levels of arguments in the equations and piece by piece reassemble the whole equation.

//finally rebuild the column formula with the new equation where the parameters are replaced bu col references.
1 ACCEPTED SOLUTION

Accepted Solutions
ian_jmp
Level X

Re: Parse a column formula and swap out parameters for column references

Not sure if this is quite what you want, or indeed, if it's general enough if it is. But adding to your code, Paul:

for(p=1, p<=NItems(ParameterSwap), p++,
	thisKey = (ParameterSwap << getKeys)[p];
	thisValue = (ParameterSwap << getValues)[p];
	Equation = Substitute(NameExpr(Equation), EvalExpr(thisKey), EvalExpr(AsColumn(dttest, thisValue)));
	Print(Equation);
);

 

View solution in original post

2 REPLIES 2
ian_jmp
Level X

Re: Parse a column formula and swap out parameters for column references

Not sure if this is quite what you want, or indeed, if it's general enough if it is. But adding to your code, Paul:

for(p=1, p<=NItems(ParameterSwap), p++,
	thisKey = (ParameterSwap << getKeys)[p];
	thisValue = (ParameterSwap << getValues)[p];
	Equation = Substitute(NameExpr(Equation), EvalExpr(thisKey), EvalExpr(AsColumn(dttest, thisValue)));
	Print(Equation);
);

 

pauldeen
Level VI

Re: Parse a column formula and swap out parameters for column references

Hi Ian, thanks!

The problem is that your solution keeps evaluating the whole equation and when it finds the letter a (one of the parameters) contained in a word somewhere it will also replace that with the replacement column. So I need to evaluate each argument only once and only if the argument is by itself and not contained in a column name. I'll rework my example to include one that fails.