【问题标题】:How to speed up the operation in R如何加快R中的操作
【发布时间】:2014-12-26 04:30:06
【问题描述】:

我的数据有一列,我正在尝试使用行中每个“/”之后的内容创建其他列。找到我之前相关问题的答案here。以下是前 5 行数据:

> dput(mydata)
structure(list(ALL = structure(c(1L, 4L, 4L, 3L, 2L), .Label = c("/ca/put/
sent_1/fe.gr/eq2_on/eq2_off",
"/ca/put/sent_1/fe.gr/eq2_on/eq2_off/cbr_LBL", "/ca/put/sent_1/fe.gr/eq2_o
n/eq2_off/cni_at.p3x.4",
"/ca/put/sent_1/fe.gr/eq2_on/eq2_off/hi.on/hi.ov"), class = "factor")), .N
ames = "ALL", class = "data.frame", row.names = c(NA, 
-5L))

以下对 5 行的样本工作正常:

res <- strsplit(as.character(mydata$ALL),"/", fixed=T)
res.df <- as.data.frame(do.call(rbind, lapply(lapply(res, factor, levels
=unique(unlist(res))), table)))

但是有数百万行它非常慢...... system.time(replicate(75000000, res.df)) 返回错误,计时停止在 563.04 21.28 644.77

(错误:无法分配大小为 2.8Gb 的向量...):

原始数据超过 4 亿行,“/”之间的字符串生成大约 100 列。有什么办法可以加快R中的上述操作?

【问题讨论】:

  • 从您上一个问题中尝试 Tyler 的回答。对我的系统进行的快速测试表明他是最快的。
  • 您是否在比测试数据更大的数据上对答案进行了基准测试?由于测试非常小,一些解决方案可能会更好地适应更大的数据,并且比您当前的方法更快。
  • 我认为问题不在于您的内存不足(这是错误消息基本上告诉您的内容)。不过,对于 R 中如此复杂的操作,400MM 行绝对是一个庞大的数据集。
  • 你为什么要复制一个值,res.dfreplicate(75000000, res.df) 返回一个包含 7500 万列的矩阵。
  • 阿南达,你是对的......泰勒的回答更快。谢谢

标签: r performance loops vectorization


【解决方案1】:

有两件事可能有助于加快res.df 的创建速度。首先,您不想在每次迭代期间都使用unique(unlist(res))。其次,你应该结合你在lapply 中使用的函数,这样你只需要对数据进行一次传递。您可以使用 functional 包中的 Compose,但也可以自己编写。

lvls <- unique(unlist(res))
helper <- function(x) 
{
    table(factor(x, levels=lvls))
}

res.df <- as.data.frame(do.call(rbind, lapply(res, helper)))

有了这么大的数据集,这可能无法解决您的问题,但这是一个开始的地方。

【讨论】:

    【解决方案2】:

    如果它们都很慢,那么您确实有其他选择;将该列写入文件,然后将其作为分隔文件读入,使用 sep = "/"。然后cbind这两个data.frames。

    它不是特别优雅,但是。

    【讨论】:

    • 我认为您误解了他们想要的输出 - 一个二进制表,其中唯一的拆分值成为列名。
    猜你喜欢
    • 2011-02-23
    • 2011-04-10
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    相关资源
    最近更新 更多