Sam
Sam

Reputation: 65

Find the first positive number in a matrix

I am trying to find a first positive or non zero number in each row of a matrix.

Here I tried to replicate my dataset:

x <- matrix(0,10,13)
y <- seq(1,10,1)
set.seed(1)

for(i in 1:10){
    x[y[i],c(y[i]:(y[i]+3))] <- runif(1,min = .5)
}

So, the data looks as follows:

           [,1]      [,2]      [,3]      [,4]      [,5]      [,6]      [,7]      [,8]      [,9]     [,10]     [,11]     [,12]    [,13]
 [1,] 0.6184363 0.6184363 0.6184363 0.6184363 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.000000
 [2,] 0.0000000 0.8788976 0.8788976 0.8788976 0.8788976 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.000000
 [3,] 0.0000000 0.0000000 0.9090922 0.9090922 0.9090922 0.9090922 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.000000
 [4,] 0.0000000 0.0000000 0.0000000 0.7781090 0.7781090 0.7781090 0.7781090 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.000000
 [5,] 0.0000000 0.0000000 0.0000000 0.0000000 0.5780575 0.5780575 0.5780575 0.5780575 0.0000000 0.0000000 0.0000000 0.0000000 0.000000
 [6,] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.9093576 0.9093576 0.9093576 0.9093576 0.0000000 0.0000000 0.0000000 0.000000
 [7,] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.5096778 0.5096778 0.5096778 0.5096778 0.0000000 0.0000000 0.000000
 [8,] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.6094725 0.6094725 0.6094725 0.6094725 0.0000000 0.000000
 [9,] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.7697144 0.7697144 0.7697144 0.7697144 0.000000
[10,] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.8575440 0.8575440 0.8575440 0.857544

I want the result to be a the indexes of first positive number in each row, so that I could recall these numbers by x[vec_Indexes].

Is there a way to do it without a for loop?

Upvotes: 0

Views: 835

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 388982

In case, the matrix contains only values 0 and 1, we can use max.col with ties = "first" which will return index of highest value in the row and in case of tie would return the first index.

max.col(x, ties.method = "first")
#[1]  1  2  3  4  5  6  7  8  9 10

and in case if it contains values other than 0 and 1 we can create a logical matrix by comparing it with 0.

x[1, 2]  <- 3
max.col(x > 0, ties.method = "first")
#[1]  1  2  3  4  5  6  7  8  9 10

Upvotes: 3

Val
Val

Reputation: 7023

Another way would be to get the array indices with which(x > 0, arr.ind = TRUE) and then get the first column with e.g. dplyr:

library(dplyr)

data.frame(which(x>0,arr.ind = T)) %>%  group_by(row) %>% slice(which.min(col))

# # A tibble: 10 x 2
# # Groups:   row [10]
# row   col
# <int> <int>
#   1     1     
#   2     2     
#   3     3     
#   4     4     
#   5     5     
#   6     6     
#   7     7     
#   8     8     
#   9     9     
#  10    10    

Upvotes: 0

Related Questions