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

Iterating Columns

I’m working on a script to iterate through a list of columns and I’ve hit a snag.  I need to be able to output the column reference in the form ":Technology Default” but every method I’ve looked at outputs "Column("Technology Default")" .  I looked this up online and it appears that the reference I need is a "column reference" when what I get is a "column object reference".  Is there a straightforward way to do what I’m after?

6 REPLIES 6
jthi
Super User

Re: Iterating Columns

What are you trying to do? You have AsColumn() and Column() (and sometimes Eval()) which you can use (for that format As Column() should generally work, but you might need to use it with expressions).

 

Edit:

Few links:

If you wish to get that format in formula for example, EvalExpr + Name Expr + As Column is the method I usually start with

Names Default To Here(1);

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

Eval(EvalExpr(
	dt << New Column(Eval Insert("^colname^*^colname^"), Numeric, Continuous, Formula(
		Expr(Name Expr(AsColumn(dt, colname))) * Expr(Name Expr(AsColumn(dt, colname)))
	));
));

 

-Jarmo
SpannerHead
Level III

Re: Iterating Columns

My end goal is to have something I can use in a formula in a new column.  Formula's only recognise columns when nominated as ":Column" as it seems.  Anyway, with the help of the information I found at this link.

 

Solved: How to replace double quotes in string - JMP User Community

 

I came up with a brute force method to get the goal done.  It is not elegant but it seems to work.  Still open to suggestions on how to do this more officially.

 

Slán

SpannerHead

dt = Current Data Table();
lst = dt << Get Column Names(string);
For(i=1,i<=NItems(lst),i++,
    colName = lst[i];
    col = Column(colName);
    Colstring = (":"||colName);
    Colref =  Parse( Eval Insert(Colstring));
    Show(Colref););
txnelson
Super User

Re: Iterating Columns

I may be barking up the wrong tree, but it seems that the issue you are having is that you are using column references in your formulas, and what you need to do is to resolve those references as the formulas are created.  Jarmo's example gives an example of doing just that, but it may be a bit confusing.  Below is an attempt to explain the issue and the solution in a very simple example

// Here is a sample script, that creates a new data table
// with 2 columns, and what we want to do, is to simply
// put the value 1 into column c1, and a 2 into column c2
// In the first example, it is done by simply running a
// for() loop and taking the index variable, "i"  and using it in
// the formula and squaring it's value.
Names Default To Here( 1 );
dt = New Table( "Example" );
dt<< add rows(1);
For( i = 1, i <= 2, i++,
	dt << New Column( "c" || Char( i ),
		formula( i^2 )
	)
);
// When each column was created, it used the value of i at that
// time within the formula.  Thus, for c1, the value of i was 1, 
// and for c2 it was 4.

// So now, if we rerun the formulas, it will take the value of 
// i at the time of rerunning each formula.
wait(5);
dt<<rerun formulas;
// After running the For() loop that was used to create the columns
// and to iterate i from 1 to 2, the loop is not stopped until i 
// becomes greater than 2.  Therefore, after running the loop, 
// i has the value of 3, so when the formulas were run, i was
// equal to 3, and thus, all column values are set to 3.

// And now, what happens if the variable i is removed.  This would 
// be as if the data table had beed saved, and then reopned in a 
// new session, and no variable named i has been created.
wait(5);
clear symbols(i);
dt<<rerun formulas;

// The point here, is that JMP does not resolve the variables in a 
// formula when the formula is placed into the column.  It is resolved
// then the formula is run.

// So to resolve this issue, we need to resolve the value of i as the
// formula is created.

Names Default To Here( 1 );
dt = New Table( "Example2" );
dt << add rows( 1 );
For( i = 1, i <= 2, i++,
	Eval(
		Eval Expr(
			dt << New Column( "c" || Char( i ), 
				formula( Expr( i ) ^ 2 ) )
		)
	)
);
// Looking into the 2 formulas, c1 has the formula
//   1^2
// and variable c2 has the formula
//   2^2
// The value of the variable i was resolved before the
// actual formula was added to column c1 and c2

// Here is an old school way of doing the same thing, but in this
// example, the JSL statement to create the formula is built in
// a literal string, and then the JSL statement is run

Names Default To Here( 1 );
dt = New Table( "Example3" );
dt << add rows( 1 );
For( i = 1, i <= 2, i++,
	Eval(
		Parse(
			"dt << New Column( \!"c" || Char( i ) || "\!", 
				formula( " || char( i ) || "^2 ) )"
		)
	)

I hope this is helpful

Jim
hogi
Level XI

Re: Iterating Columns

instead of the "brute force"

    Colstring = (":"||colName);
    Colref =  Parse( Eval Insert(Colstring));

a more elegant way is:

Colref= Name Expr (As Column(colName))

-> see @jthi's reply.
It already helped many other users : Expression Handling in JMP: Tipps and Trapdoors 

 

by the way:
in your example, you can get the Colref(s) directly via Get Column Names - just remove the STRING argument.
They don't have the ":" in front, but this is just cosmetics

dt = Current Data Table();
lst = dt << Get Column Names();
For( i = 1, i <= N Items( lst ), i++,
	Show( lst[i] );
	Show( lst[i][5] );
); 

 

hogi
Level XI

Re: Iterating Columns

If you prefer the column names with  leading ":", you can use a trick:
ask each of them for the name. 

columnNames = current data table() << Get Column Names;
for (i=1, i<= Nitems(columnNames),i++,columnNames[i]<< get name() );
show(columnNames) // -> column names with leading ":"

 

jthi
Super User

Re: Iterating Columns

I won't generally mess with column references like that in JMP because it is too annoying to manage them -> I use strings of the column names and use them as needed with Column(), As Column(), Eval() or NameExpr(AsColumn()) (if I for some reason need to use column references (Column("something")), I will convert those to strings using << Get Name when I need to use those).

 

Names Default To Here(1);

dt = open("$SAMPLE_DATA/Big Class.jmp");
col1 = "height";
col2 = "weight";

// Good way but can be (sometimes) difficult to read Eval(EvalExpr( dt << New Column("mycol1", Numeric, Continuous, Formula( Expr(Name Expr(AsColumn(dt, col1))) * Expr(Name Expr(AsColumn(dt, col2))) )) ));
// might be easier to read Eval(Substitute( Expr(dt << New Column("mycol2", Numeric, Continuous, Formula( _firstcol_ * _secondcol_ ))), Expr(_firstcol_), Name Expr(AsColumn(dt, col1)), Expr(_secondcol_), Name Expr(AsColumn(dt, col2)) )); // "reusable" ref1 = Name Expr(AsColumn(dt, col1)); // this will return :height BUT you will generally still need Name Expr() to use it ref2 = Name Expr(AsColumn(dt, col2)); // wont work, because ref1 will get evaluated for "current" row Eval(EvalExpr( dt << New Column("mycol3", Numeric, Continuous, Formula( Expr(ref1) * Expr(ref2) )) )); // will work Eval(EvalExpr( dt << New Column("mycol3", Numeric, Continuous, Formula( Expr(Name Expr(ref1)) * Expr(Name Expr(ref2)) )) ));

If you tried to use just

dt << New Column("mycol4", Numeric, Continuous, Formula(
	ref1 * ref2
));

you will end up with formula like ref1*ref2 as those are not evaluated to the formula

jthi_0-1715437666962.png

 

Few more links:

 

-Jarmo