【问题标题】:Quickly combine logical matrices with & in R在 R 中使用 & 快速组合逻辑矩阵
【发布时间】:2020-08-19 09:27:33
【问题描述】:

我有一个很大的逻辑矩阵,需要使用& 操作将每一列与一个向量组合在一起。现在我正在遍历列,但这需要一段时间,因为有超过 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 &amp; bool 有效,不是吗?
  • @r2evans 是的,我已经根据 OP 的代码进行了检查,all((mx &amp; bool) == out)TRUE
  • 是的,我不敢相信我没有先尝试这个。谢谢大家。

标签: r binary vectorization logical-operators processing-efficiency


【解决方案1】:

我认为您想要的结果是 mx 的暗淡,每行 &amp;ed 具有各自的单个值 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

(显示cbinded 数据只是为了将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

【讨论】:

    【解决方案2】:

    在这种情况下很容易:

    mx & bool
    

    boolmx 中的所有列回收

    identical(mx & bool, out)
    

    输出:

    [1] TRUE
    

    【讨论】:

      【解决方案3】:

      您可以尝试使用 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 
      

      【讨论】:

      • 谢谢,我是 data.table 的粉丝,但我认为 mx &amp; bool 解决方案在这里实际上更快
      • 同意,我刚试过。我不知道&amp; 运算符默认是矢量化的;很高兴知道。
      • &amp; 是按定义和意图进行矢量化的,实际上...与 &amp;&amp; 相反,后者有意矢量化
      猜你喜欢
      • 2013-06-22
      • 1970-01-01
      • 2017-06-06
      • 1970-01-01
      • 1970-01-01
      • 2018-01-23
      • 2018-09-03
      • 2018-02-11
      • 1970-01-01
      相关资源
      最近更新 更多