【发布时间】:2016-07-08 07:51:46
【问题描述】:
我对一些用于替换每列缺失值的解决方案进行了基准测试。
set.seed(11)
df <- data.frame(replicate(3, sample(c(1:5, -99), 6, rep = TRUE)))
names(df) <- letters[1:3]
fix_na <- function(x) {
x[x == -99] <- NA
}
microbenchmark(
for(i in seq_along(df)) df[, i] <- fix_na(df[, i]),
for(i in seq_along(df)) df[[i]] <- fix_na(df[[i]]),
df[] <- lapply(df, fix_na)
)
Unit: microseconds
expr min lq mean median uq max neval
for (i in seq_along(df)) df[, i] <- fix_na(df[, i]) 179.167 191.9060 206.1650 204.2335 211.630 364.497 100
for (i in seq_along(df)) df[[i]] <- fix_na(df[[i]]) 83.420 92.8715 104.5787 98.0080 109.309 204.645 100
df[] <- lapply(df, fix_na) 105.199 113.4175 128.0265 117.9385 126.979 305.734 100
为什么 [[]] 运算符对数据帧进行子集化的速度比 [,] 运算符快 2 倍?
编辑
我包含了来自 docendo discimus 的两个推荐调用并增加了数据量。
set.seed(11)
df1 <- data.frame(replicate(2000, sample(c(1:5, -99), 500, rep = TRUE)))
df2 <- df1
df3 <- df1
df4 <- df1
df5 <- df1
结果改变是的,但我的问题仍然存在:[[]] 比 [,] 执行得更快
Unit: milliseconds
expr min lq mean median uq
for (i in seq_along(df1)) df1[, i] <- fix_na(df1[, i]) 301.06608 356.48011 377.31592 372.05625 392.73450 472.3330
for (i in seq_along(df2)) df2[[i]] <- fix_na(df2[[i]]) 238.72005 287.55364 301.35651 298.05950 314.04369 386.4288
df3[] <- lapply(df3, fix_na) 170.53264 189.83858 198.32358 193.43300 202.43855 284.1164
df4[df4 == -99] <- NA 75.05571 77.64787 85.59757 80.72697 85.16831 363.2223
is.na(df5) <- df5 == -99 74.44877 77.81799 84.22055 80.06496 83.01401 347.5798
【问题讨论】:
-
如果您在小数据集上进行基准测试,它不会给出正确的输出
-
您可以在基准测试中再添加两种方法:
df[df == -99] <- NA和is.na(df) <- df == -99 -
@Arun 感谢您的提示。但据我所知,$ 运算符是 [["x", exact = FALSE]] 的缩写。因此,与 [,] 运算符相比,它并没有真正的帮助,或者?
-
在您的问题中,您不比较
[VS[[。你可以比较[.data.frame和[[.data.frame,但实际上你也在比较[<-.data.frame和[[<-.data.frame。您可以浏览这些函数并根据参数的数量等找到可能(如果有的话)增加计算时间的内容。