R 编程:Previous/preceding/successive 列的逻辑测试

R Programming: Logical test of Previous/preceding/successive Column

我有一个名为 'ft' 的矩阵,它是一些逻辑测试的结果。 这是示例,[10,5] 的矩阵。 在实际工作中,它将是数千行、更多列和大约数百个矩阵。

     [,1] [,2] [,3] [,4] [,5]
 [1,]    1    1    1    1    1
 [2,]    1    1    1    1    1
 [3,]    0    1    1    1    1
 [4,]    1    1    1    1    1
 [5,]    1    1    1    1    1
 [6,]    1    1    1    1    1
 [7,]    1    1    1    1    1
 [8,]    1    1    1    1    1
 [9,]    1    1    1    1    1
[10,]    1    0    1    1    1

我需要对上一列中的值进行逻辑测试。如果前一列的值为零,则该列的其余部分将为零。 例如,向量 [3,1] 的值为零,因此行 [3,] 中的其余列将为零。同样,[10,2] 中的元素为零,因此行 [10,3:5] 将为零 所以新矩阵的结果将是这样的:

     [,1] [,2] [,3] [,4] [,5]
 [1,]    1    1    1    1    1
 [2,]    1    1    1    1    1
 [3,]    0    0    0    0    0
 [4,]    1    1    1    1    1
 [5,]    1    1    1    1    1
 [6,]    1    1    1    1    1
 [7,]    1    1    1    1    1
 [8,]    1    1    1    1    1
 [9,]    1    1    1    1    1
[10,]    1    0    0    0    0

我是 R 的新手,我尝试过如下几种选择:

ctes=cbind(ftes[,1], (ftes[,2:t]==1 & ctes[,-1]==1))

但这是完全错误的。 如何使用矢量化方法而不是循环测试有效地做到这一点。

可能有更简单的方法,但这应该可行:

zeros <- which(ft==0,arr.ind=TRUE)
sapply(1:nrow(zeros), function(x) ft[zeros[x,1], zeros[x,2]:ncol(ft)] <<- 0)
#> ft
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    1    1    1    1    1
# [2,]    1    1    1    1    1
# [3,]    0    0    0    0    0
# [4,]    1    1    1    1    1
# [5,]    1    1    1    1    1
# [6,]    1    1    1    1    1
# [7,]    1    1    1    1    1
# [8,]    1    1    1    1    1
# [9,]    1    1    1    1    1
#[10,]    1    0    0    0    0

这不是向量化的,但循环只延伸到包含零的行,而不是整个矩阵。根据矩阵的密度,这可能会或可能不会产生巨大差异。

数据

ft <- structure(c(1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
      1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
      1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
      1L, 1L, 1L, 1L, 1L), .Dim = c(10L, 5L), .Dimnames = list(NULL, NULL))

我不认为 base R 提供了解决这个问题的矢量化方法,但如果效率很重要,你可以尝试 matrixStats

matrixStats::rowCummins(ft)
#       [,1] [,2] [,3] [,4] [,5]
#  [1,]    1    1    1    1    1
#  [2,]    1    1    1    1    1
#  [3,]    0    0    0    0    0
#  [4,]    1    1    1    1    1
#  [5,]    1    1    1    1    1
#  [6,]    1    1    1    1    1
#  [7,]    1    1    1    1    1
#  [8,]    1    1    1    1    1
#  [9,]    1    1    1    1    1
# [10,]    1    0    0    0    0

200MB 大小矩阵的基准

set.seed(123)
Bigft <- matrix(sample(0:1, 5e7, replace = TRUE), ncol = 100)
system.time(matrixStats::rowCummins(Bigft))
# user  system elapsed 
# 0.08    0.01    0.10