在 R 中使用 & 快速组合逻辑矩阵
Quickly combine logical matrices with & in R
我有一个很大的逻辑矩阵,需要使用 &
运算将每一列与一个向量组合起来。现在我正在遍历列,但这需要一段时间,因为有超过 100 万行。有没有更快的、可能是矢量化的方法来做到这一点?
mx <- replicate(10, sample(c(T,F), size = 1000, replace = T)) # 1000 rows x 10 columns
bool <- sample(c(T,F), size = 1000, replace = T) # 1000 elements
out <- apply(mx1, 2, function(x) {
x & bool
})
对于上下文,此数据来自基因表达矩阵,其中 1 行 = 1 个单元格
我认为您想要一个 mx
的结果,其中每一行 &
都与 bool
的相应单个值进行了编辑。我觉得你不做任何外在都很好。
set.seed(42)
mx <- replicate(4, sample(c(T,F), size = 10, replace = T)) # 1000 rows x 10 columns
bool <- sample(c(T,F), size = 10, replace = T) # 1000 elements
cbind(mx, NA, bool)
# bool
# [1,] FALSE TRUE FALSE FALSE NA TRUE
# [2,] FALSE FALSE TRUE FALSE NA TRUE
# [3,] TRUE FALSE FALSE TRUE NA TRUE
# [4,] FALSE TRUE FALSE FALSE NA FALSE
# [5,] FALSE TRUE TRUE TRUE NA TRUE
# [6,] FALSE FALSE FALSE FALSE NA FALSE
# [7,] FALSE FALSE TRUE TRUE NA FALSE
# [8,] TRUE TRUE FALSE TRUE NA FALSE
# [9,] FALSE TRUE TRUE FALSE NA FALSE
# [10,] FALSE FALSE FALSE FALSE NA FALSE
(显示 cbind
ed 数据只是为了将 bool
值与 mx
的每一行对齐。)
因此,任何带有 bool
false 的行都应导致所有 FALSE
:
mx & bool
# [,1] [,2] [,3] [,4]
# [1,] FALSE TRUE FALSE FALSE
# [2,] FALSE FALSE TRUE FALSE
# [3,] TRUE FALSE FALSE TRUE
# [4,] FALSE FALSE FALSE FALSE
# [5,] FALSE TRUE TRUE TRUE
# [6,] FALSE FALSE FALSE FALSE
# [7,] FALSE FALSE FALSE FALSE
# [8,] FALSE FALSE FALSE FALSE
# [9,] FALSE FALSE FALSE FALSE
# [10,] FALSE FALSE FALSE FALSE
验证:
out <- apply(mx, 2, function(x) x & bool)
identical(out, mx & bool)
# [1] TRUE
microbenchmark::microbenchmark(apply(mx, 2, function(x) x & bool), mx & bool)
# Unit: nanoseconds
# expr min lq mean median uq max neval
# apply(mx, 2, function(x) x & bool) 31100 32400 53029 34400 39750 1644700 100
# mx & bool 400 600 824 700 900 3200 100
使用更大的矩阵:
mx <- replicate(10, sample(c(T,F), size = 1000, replace = T)) # 1000 rows x 10 columns
bool <- sample(c(T,F), size = 1000, replace = T) # 1000 elements
dim(mx)
# [1] 1000 10
length(bool)
# [1] 1000
microbenchmark::microbenchmark(apply(mx, 2, function(x) x & bool), mx & bool)
# Unit: microseconds
# expr min lq mean median uq max neval
# apply(mx, 2, function(x) x & bool) 336.1 489.70 621.647 605.25 696.05 1999.9 100
# mx & bool 65.0 94.25 135.260 129.20 159.50 385.4 100
在这种情况下很容易:
mx & bool
bool
为 mx
中的所有列回收
identical(mx & bool, out)
输出:
[1] TRUE
您可以尝试使用 data.table 软件包:
n <- 1000000
mx <- replicate(10, sample(c(T,F), size = n, replace = T)) # n rows x 10 columns
bool <- sample(c(T,F), size = n, replace = T) # n elements
# original solution
system.time(
out <- apply(mx, 2, function(x) {
x & bool
})
)
# user system elapsed
# 0.20 0.02 0.22
# using data.table, approx. half the time
dt <- data.table(mx)
system.time(
out2 <- dt[, lapply(.SD, function(x){x & bool})]
)
# user system elapsed
# 0.11 0.00 0.11
我有一个很大的逻辑矩阵,需要使用 &
运算将每一列与一个向量组合起来。现在我正在遍历列,但这需要一段时间,因为有超过 100 万行。有没有更快的、可能是矢量化的方法来做到这一点?
mx <- replicate(10, sample(c(T,F), size = 1000, replace = T)) # 1000 rows x 10 columns
bool <- sample(c(T,F), size = 1000, replace = T) # 1000 elements
out <- apply(mx1, 2, function(x) {
x & bool
})
对于上下文,此数据来自基因表达矩阵,其中 1 行 = 1 个单元格
我认为您想要一个 mx
的结果,其中每一行 &
都与 bool
的相应单个值进行了编辑。我觉得你不做任何外在都很好。
set.seed(42)
mx <- replicate(4, sample(c(T,F), size = 10, replace = T)) # 1000 rows x 10 columns
bool <- sample(c(T,F), size = 10, replace = T) # 1000 elements
cbind(mx, NA, bool)
# bool
# [1,] FALSE TRUE FALSE FALSE NA TRUE
# [2,] FALSE FALSE TRUE FALSE NA TRUE
# [3,] TRUE FALSE FALSE TRUE NA TRUE
# [4,] FALSE TRUE FALSE FALSE NA FALSE
# [5,] FALSE TRUE TRUE TRUE NA TRUE
# [6,] FALSE FALSE FALSE FALSE NA FALSE
# [7,] FALSE FALSE TRUE TRUE NA FALSE
# [8,] TRUE TRUE FALSE TRUE NA FALSE
# [9,] FALSE TRUE TRUE FALSE NA FALSE
# [10,] FALSE FALSE FALSE FALSE NA FALSE
(显示 cbind
ed 数据只是为了将 bool
值与 mx
的每一行对齐。)
因此,任何带有 bool
false 的行都应导致所有 FALSE
:
mx & bool
# [,1] [,2] [,3] [,4]
# [1,] FALSE TRUE FALSE FALSE
# [2,] FALSE FALSE TRUE FALSE
# [3,] TRUE FALSE FALSE TRUE
# [4,] FALSE FALSE FALSE FALSE
# [5,] FALSE TRUE TRUE TRUE
# [6,] FALSE FALSE FALSE FALSE
# [7,] FALSE FALSE FALSE FALSE
# [8,] FALSE FALSE FALSE FALSE
# [9,] FALSE FALSE FALSE FALSE
# [10,] FALSE FALSE FALSE FALSE
验证:
out <- apply(mx, 2, function(x) x & bool)
identical(out, mx & bool)
# [1] TRUE
microbenchmark::microbenchmark(apply(mx, 2, function(x) x & bool), mx & bool)
# Unit: nanoseconds
# expr min lq mean median uq max neval
# apply(mx, 2, function(x) x & bool) 31100 32400 53029 34400 39750 1644700 100
# mx & bool 400 600 824 700 900 3200 100
使用更大的矩阵:
mx <- replicate(10, sample(c(T,F), size = 1000, replace = T)) # 1000 rows x 10 columns
bool <- sample(c(T,F), size = 1000, replace = T) # 1000 elements
dim(mx)
# [1] 1000 10
length(bool)
# [1] 1000
microbenchmark::microbenchmark(apply(mx, 2, function(x) x & bool), mx & bool)
# Unit: microseconds
# expr min lq mean median uq max neval
# apply(mx, 2, function(x) x & bool) 336.1 489.70 621.647 605.25 696.05 1999.9 100
# mx & bool 65.0 94.25 135.260 129.20 159.50 385.4 100
在这种情况下很容易:
mx & bool
bool
为 mx
identical(mx & bool, out)
输出:
[1] TRUE
您可以尝试使用 data.table 软件包:
n <- 1000000
mx <- replicate(10, sample(c(T,F), size = n, replace = T)) # n rows x 10 columns
bool <- sample(c(T,F), size = n, replace = T) # n elements
# original solution
system.time(
out <- apply(mx, 2, function(x) {
x & bool
})
)
# user system elapsed
# 0.20 0.02 0.22
# using data.table, approx. half the time
dt <- data.table(mx)
system.time(
out2 <- dt[, lapply(.SD, function(x){x & bool})]
)
# user system elapsed
# 0.11 0.00 0.11