Reputation: 65
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
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
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