I am trying to optimize some code that I have written as it is very slow for large datasets. I am not sure if the following can be done with matrix operations and I would appreciate if someone had any suggestions to make it faster.
I have a matrix with zeros and integers and I would like to shift down the entries of the individual columns by the absolute number of the integer in the the entry.
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 -4 0
[3,] 4 0 0
[4,] -3 -2 0
[5,] 0 2 -1
[6,] 2 -2 0
[7,] 0 0 0
[8,] -3 -3 0
The code I am using is the following:
#data
A<-matrix(data=c(0,0,4,-3,0,2,0,-3,0,-4,0,-2,2,-2,0,-3,0,0,0,0,-1,0,0,0),nrow=8,ncol=3)
#shift function
shift<-function(x)
{
#create the output matrix
out<-matrix(data=0,nrow=8,ncol=1)
#for loop to create the shift matrix
for(i in seq(1,8,by=1))
{
if(i+abs(x[i])<=8)
{
#find the non zero
if(x[i]!=0)
{
#if there is already a number put zero
if(out[i+abs(x[i]),1]!=0)
{
out[i+abs(x[i]),1]=0
} else {
#shift
out[i+abs(x[i]),1]=x[i]
}
}
}
}
#return object
return(out)
}
#run the logic
shift_mat<-sapply(1:ncol(A),FUN=function(k) shift(A[,k]))
and the result is:
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
[3,] 0 0 0
[4,] 0 0 0
[5,] 0 0 0
[6,] 0 0 -1
[7,] 0 2 0
[8,] 2 -2 0
The rules are the following for every column:
- starting from the top find first entry that is different than
zero
- shift down by the absolute numbers of that entry
- if there is another entry at the targeted point put zero
- repeat for the next column
Thanks,
Nikos
See Question&Answers more detail:
os