我有一个名为'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))
但这是完全错误的。 如何使用矢量化方法而不是循环测试有效地做到这一点。
答案 0 :(得分:2)
我不认为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
答案 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))