【问题标题】:R: optimize subsetting and dropping factor levelsR:优化子集和删除因子水平
【发布时间】:2016-08-24 21:08:43
【问题描述】:

我正在优化被多次调用的 R 代码,发现以下两个命令消耗的时间最多:

dataset <- dataset[which(dataset$responder==T),]

  for (i in 1:ncol(dataset))
    if (is.factor(dataset[,i]))
      dataset[,i] <- dataset[,i][drop=T]

我尝试谷歌搜索,看看是否有办法优化这些,但没有找到任何东西。有没有办法改进这些线路,或者这只是尽可能快?理想情况下,解决方案不应要求编译或使代码不可读。

【问题讨论】:

  • dataset[dataset$responder,] 不会比 dataset[which(dataset$responder==T),] 快吗?
  • @BenBolker:谢谢你的建议。看起来 which() 是一个非常优化的函数。做一些模拟,我得到平均 114 毫秒 which() 和平均 110 毫秒,直接使用逻辑向量。中位数从 87 提高到 77。但是,当使用您的建议时,用户必须确保数据集中没有 NA,因为它们会在输出中产生 NA 行。
  • @BenBolker: isTRUE 是相同(TRUE, x) 的缩写,不应在这种情况下使用,因为如果向量的长度大于 1,它将始终返回 FALSE。

标签: r optimization


【解决方案1】:

使用矢量化,代码变得稍微快了一点。

dataset <- droplevels(dataset[dataset$responder==T,])

测试

library(microbenchmark)

# data
testdata=data.frame(type=c(rep("a", 5000), rep("b", 5000), rep("c",5000)), 
     responder=c(rep(TRUE, 4000), rep(FALSE,11000)))

# functions
orig <- function(){ ...code in question... }
vect <- function(){ ...code in answer... }

 microbenchmark(orig())
Unit: microseconds
   expr    min      lq     mean  median      uq      max neval
 orig() 638.27 654.929 793.7463 668.535 688.643 6650.592   100
 microbenchmark(vect())
Unit: microseconds
   expr     min       lq     mean  median     uq      max neval
 vect() 618.021 636.0365 768.6891 643.895 665.27 5122.989   100

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    相关资源
    最近更新 更多