获取矩阵每一列的第一个TRUE元素的索引,但是索引必须>到n

时间:2019-01-13 23:22:20

标签: r

所以我有一个像这样的逻辑向量矩阵:

r=10
c=10
m1 <- matrix(runif(r*c)>0.5, r, c)
> m1
       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
 [1,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE
 [2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
 [3,]  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE
 [4,] FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE
 [5,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE
 [6,]  TRUE FALSE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE
 [7,] FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE
 [8,] FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE
 [9,]  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[10,]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE

还有这样的向量:

v1 <- round(runif(10,1,10))
> v1
 [1] 6 5 7 5 5 4 4 2 1 10

如何获取m1的每列的第一个TRUE值的10个索引> v1?

因此,在此示例中,我想获取此向量:

[1] 9 7 8 NA 6 5 7 3 3 NA

感谢您的帮助

3 个答案:

答案 0 :(得分:1)

一种选择是使用mapply。这是使用固定随机种子的可重现示例。

set.seed(2017)
r <- 10
c <- 10
m1 <- matrix(runif(r*c) > 0.5, r, c)    
v1 <- round(runif(10,1,10))   

mapply(function(x, y) { idx <- which(x == TRUE); idx[idx > y][1]}, as.data.frame(m1), v1, USE.NAMES = F)
#[1] NA NA  3  5  8  2  9  8  2  2

说明:对于m1的每一列,我们提取TRUEidx个条目的索引;然后,我们返回idx的第一个索引,该索引大于v1中与列号匹配的条目;如果不存在这样的数字,它将自动返回NA

注意:为了使mapply同时循环遍历m1的列和v1的条目,我们需要将m1转换为data.frame


样本数据

使用上述固定的随机种子,样本为数据

m1
#       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
# [1,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE
# [2,]  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
# [3,] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE
# [4,] FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
# [5,]  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
# [6,]  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
# [7,] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
# [8,] FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE FALSE FALSE
# [9,] FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE
#[10,] FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE

v1
#[1]  9 10  2  3  6  1  5  6  1  1

答案 1 :(得分:1)

是您想要的吗?

r=10
c=10
set.seed(42)
m1 <- matrix(runif(r*c)>0.5, r, c)
set.seed(314)
v1 <- round(runif(10,1,10))

out = sapply(1:10, function(i) 
{ 
  v = v1[i]
  r = m1[v:10,i]
  j = which(r)[1] + v - 1
})

out

我的输入(可以用种子复制)

> m1
       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
 [1,]  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE
 [2,]  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE
 [3,] FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
 [4,]  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE
 [5,]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE
 [6,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
 [7,]  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
 [8,] FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE
 [9,]  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE
[10,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE

> v1
 [1] 2 3 8 3 3 4 3 4 6 8

我的输出

> out
 [1]  4  6 10  4  4  6  4  6 NA  9

答案 2 :(得分:0)

使用TRUE获取每个which的行/列索引。 which中的代码结合使用sweep和原始TRUE / FALSE mat对象来计算行计数是否更高。然后,使用match将这些索引作为每个列中第一个匹配项的子集,当该列中没有值时,它们将返回NA

# using Maurits' data

matsel <- which(sweep(row(mat), 2, v1, FUN=`>`) & mat, arr.ind=TRUE)
matsel[,"row"][match(seq_len(ncol(mat)), matsel[,"col"])]
#[1] NA NA  3  5  8  2  9  8  2  2

这也应该很好地扩展,因为它避免了任何对列或行的循环。唯一需要注意的是matsel变大并在存储每个TRUE值的位置时占用内存。