cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Submit your abstract to the call for content for Discovery Summit Americas by April 23. Selected abstracts will be presented at Discovery Summit, Oct. 21- 24.
Discovery is online this week, April 16 and 18. Join us for these exciting interactive sessions.
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