João Carvalho
João Carvalho

Reputation: 159

Row Index where one column has a non-zero entry

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

Answers (2)

moodymudskipper
moodymudskipper

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

Terru_theTerror
Terru_theTerror

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

Related Questions