cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
JMP is taking Discovery online, April 16 and 18. Register today and join us for interactive sessions featuring popular presentation topics, networking, and discussions with the experts.
Choose Language Hide Translation Bar
uday_guntupalli
Level VIII

Alternative to Lag() when working with matrices instead of data tables

All, 
      Is there an alternative to the lag() that I could use when working with matrices instead of data tables ? Esentially, I would like to be able to look at the value of the previous row of my column in a matrix to determine the value of current row. This can easily be acheived using the lag() function in a data table. What is an effective way other than looping to acheive this if working with matrices ? 

 

dt = New Table("Test"); 

dt << New Column("Random-1",Numeric,Continuous,<< set values(Random Index(10^3,10^2))); 

dt << New Column("AltToLag",Numeric,Continuous,Formula(If(Row()==1,0,Lag(:Name("Random-1")))));
Best
Uday
11 REPLIES 11
vince_faller
Super User (Alumni)

Re: Alternative to Lag() when working with matrices instead of data tables

Sure.  So if we look at your formula (other than the first row = 0)

 


	If( Mod( Lag( :RandomList ), 2 ) == 0,
		:RandomList[Row()] + 1,
		:RandomList[Row()] - 1
	)

I see it as 3 parts, the lag, the mod == 0 check of the lag, and the else expression of that.  

 

 

So I first do the lag

 

lv = lag_matrix(v, 1);

 

then I get the mod vector  

mod_vector = lv / 2 - floor(lv/2);

but I just realized mod works on vectors so you could do

mod_vector = mod(lv, 2);

 

which is significantly faster

 

then I get a boolean vector by doing 

mod_vector == 0 and loc() it to find the rows where the mod(2) of the lag(1) is 0

loc_vector = loc(mod_vector==0);

loc_vector is the rows that match your if statement 

Mod( Lag( :RandomList ), 2 ) == 0

 

then to get the else statement rows, I invert the selection by making a vector of all 1s and setting the loc_vector rows to 0 and doing a loc()

 

 

invert_vector = J(nrows(v), 1);
invert_vector[loc_vector] = 0;
invert_vector = loc(invert_vector);

so if you concatted the two vectors and sorted, it should just be 1::nrows()

 

after that I just set the rows for the if expression to +1 and the else expression to -1

 

 

v[loc_vector] = v[loc_vector] + 1;
v[invert_vector] = v[invert_vector] - 1;

and finally set the first row to 0

 

 

v[1] = 0;

 

 

 

 

Vince Faller - Predictum
Craige_Hales
Super User

Re: Alternative to Lag() when working with matrices instead of data tables

Here's a variation of Vince's solution I was playing with. It might or might not capture the requirements but might explain how to do the manipulations you need.

R = [4, 6, 6, 5, 8, 7];
lag = 1;
// describe the adjustment
modamount = [1, -1];
// lagged values dont need the last value
lagged = R[1 :: N Rows( R ) - lag];// [4, 6, 6, 5, 8]
// adjustment is based on lagged values. add 1 for indexing.
adjust = modamount[1 + Mod( lagged, 2 )];// [1, 1, 1, -1, 1]
// source data does not need the first value
source = R[1 + lag :: N Rows( R )]; // [6, 6, 5, 8, 7]
// combine the adjustment with the source
combine = adjust + source; //    [7, 7, 6, 7, 8]
// prepend a zero
answer = 0 |/ combine; // [0, 7, 7, 6, 7, 8]
Craige