【发布时间】:2012-01-09 23:53:01
【问题描述】:
我想为数据框的每一行运行一个操作,更改一列。我是一个 apply/ddply/sqldf 人,但是当它们有意义时我会使用循环,我认为这是其中之一。这种情况很棘手,因为要更改的列取决于逐行更改的信息;根据一个单元格中的信息,我应该只更改该行中其他十个单元格中的一个。有 75 列和 20000 行,操作需要 10 分钟,而我的脚本中的每个其他操作需要 0-5 秒,最多 10 秒。我已将我的问题简化为下面非常简单的测试用例。
n <- 20000
t.df <- data.frame(matrix(1:5000, ncol=10, nrow=n) )
system.time(
for (i in 1:nrow(t.df)) {
t.df[i,(t.df[i,1]%%10 + 1)] <- 99
}
)
十列需要 70 秒,当 ncol=50 时需要 360 秒。太疯狂了。循环是错误的方法吗?有没有更好、更有效的方法来做到这一点?
我已经尝试将嵌套项 (t.df[i,1]%%10 + 1) 初始化为 for 循环外的列表。它节省了大约 30 秒(总共 10 分钟),但使上面的示例代码更加复杂。所以它有帮助,但不是解决方案。
我目前最好的想法是在准备这个测试用例时产生的。对我来说,只有 10 列是相关的(75-11 列是不相关的)。由于运行时间很大程度上取决于列数,因此我可以在排除不相关列的数据框上运行上述操作。这将使我减少一分钟多一点。但是“带有嵌套索引的 for 循环”甚至是思考我的问题的最佳方式吗?
【问题讨论】:
-
+1 用于简化的测试用例、清晰描述的问题和可重现的示例。
标签: performance r for-loop nested vectorization