Reputation: 159
I think this might be a repeated question but I can't find the answer so here it goes. If I have a matrix X:
> X
[,1] [,2] [,3] [,4] [,5]
[1,] 1 4 55 1 8
[2,] 48 2 0 1 2
[3,] 67 23 53 55 78
[4,] 0 78 0 0 0
[5,] 85 91 23 65 83
What is the easiest way to get the row index where one entry is non-zero and all others are zero? I have tried:
test <- which(X[,2] != 0 & X[,-2] == 0)
And ideally I would like the result to be: 4. But, that's not what happens... I get that which()
gives me the index (row and column) so it's probably not the way to solve this... Any ideas?
Thanks in advance!
Upvotes: 0
Views: 74
Reputation: 47330
X <- as.matrix(read.table(text="
1 4 55 1 8
48 2 0 1 2
67 23 53 55 78
0 78 0 0 0
85 91 23 65 83"))
which(rowSums(X!=0)==1)
# [1] 4
Here are 2 ways to correct your approach, note they focus on observing column 2 while my solution doesn't:
which(X[,2] != 0 & rowSums(X[,-2] != 0)==0) # [1] 4
which(X[,2] & !apply(X[,-2],1,any,0)) # [1] 4
Your approach fails because X[,-2] == 0
is a matrix of booleans, not a vector as you'd want it to be.
If you want to do this for your all columns separately you can use lapply
:
lapply(seq(ncol(X)),function(i) which(X[,i] != 0 & rowSums(X[,-i] != 0)==0))
Upvotes: 2
Reputation: 5017
Try this easy example code:
m<-as.matrix(cbind(a=c(1,1,1,0,0,1),b=c(1,1,1,1,0,0),c=c(1,1,1,0,0,0)))
> m
a b c
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
[4,] 0 1 0
[5,] 0 0 0
[6,] 1 0 0
>
> #Row detection
> which(rowSums(m!=0)==1)
[1] 4 6
>
> #Column with elemnte !=0
> apply(m[which(rowSums(m!=0)==1),],1,which.max)
[1] 2 1
Upvotes: 1