dplyr杂交选项现在比BaseR子集重新分配快30%左右。在一个100米的数据池上mutate_all(~replace(., is.na(.), 0))比基数R快半秒d[is.na(d)]
如果你在为大量的数据而挣扎,data.table是最快的选择:比标准快40%。基R接近。它还可以修改现有的数据,有效地允许您一次处理几乎两倍的数据。
其他有用的潮汐替换方法的聚类
地点:指数 mutate_at(c(5:10), ~replace(., is.na(.), 0))
直接参考 mutate_at(vars(var5:var10), ~replace(., is.na(.), 0))
固定匹配 mutate_at(vars(contains("1")), ~replace(., is.na(.), 0))或代替
contains(),试试看
ends_with(),starts_with()
模式匹配 mutate_at(vars(matches("\\d{2}")), ~replace(., is.na(.), 0))
有条件:
(只更改数值(列),并保留字符串(列)。)整数 mutate_if(is.integer, ~replace(., is.na(.), 0))
双打 mutate_if(is.numeric, ~replace(., is.na(.), 0))
弦 mutate_if(is.character, ~replace(., is.na(.), 0))
完整的分析-
更新为dplyr 0.8.0:函数使用purrr格式~符号:替换已废弃的funs()争论。
测试的方法:# Base R: baseR.sbst.rssgn
x[[j]][is.na(x[[j]])] = 0 }# tidyverse## dplyrdplyr_if_else
}dplyr_coalesce
s.list(setNames(rep(0, 10), as.list(c(paste0("var", 1:10)))))) }## hybrid hybrd.ifelse
s.na(.), 0, .)) }hybrd.replace_na
x, ~replace(., is.na(.), 0)) }hybrd.rplc_at.idx
unction(x) { mutate_at(x, vars(var1:var10), ~replace(., is.na(.), 0)) }hybrd.rplc_at.stw
th("var")), ~replace(., is.na(.), 0)) }hybrd.rplc_at.ctn
) }hybrd.rplc_at.mtc
) { mutate_if(x, is.numeric, ~replace(., is.na(.), 0)) }# data.table library(data.table)DT.for.set.nms
(j in names(x))
set(x,which(is.na(x[[j]])),j,0) }DT.for.set.sqln
set(x,which(is.na(x[[j]])),j,0) }DT.fnafill
{ setnafill(df, fill=0)}
这一分析的代码:library(microbenchmark)# 20% NA filled dataframe of 10 Million rows and 10 columnsset.seed(42) # to recreate the exact dataframedfN
dimnames = list(NULL, paste0("var", 1:10)),
ncol = 10))# Running 600 trials with each replacement method # (the functions are excecuted locall
y - so that the original dataframe remains unmodified in all cases)perf_results
hybrid.ifelse = hybrid.ifelse(copy(dfN)),
dplyr_if_else = dplyr_if_else(copy(dfN)),
hybrd.replace_na = hybrd.replace_na(copy(dfN)),
baseR.sbst.rssgn = baseR.sbst.rssgn(copy(dfN)),
baseR.replace = baseR.replace(copy(dfN)),
dplyr_coalesce = dplyr_coalesce(copy(dfN)),
tidyr_replace_na = tidyr_replace_na(copy(dfN)),
hybrd.replace = hybrd.replace(copy(dfN)),
hybrd.rplc_at.ctn= hybrd.rplc_at.ctn(copy(dfN)),
hybrd.rplc_at.nse= hybrd.rplc_at.nse(copy(dfN)),
baseR.for = baseR.for(copy(dfN)),
hybrd.rplc_at.idx= hybrd.rplc_at.idx(copy(dfN)),
DT.for.set.nms = DT.for.set.nms(copy(dfN)),
DT.for.set.sqln = DT.for.set.sqln(copy(dfN)),
times = 600L)
结果摘要> print(perf_results)Unit: milliseconds
expr min lq mean median uq max neval
hybrd.ifelse 6171.0439 6339.7046 6425.221 6407.397 6496.992 7052.851 600
dplyr_if_else 3737.4954 3877.0983 3953.857 3946.024 4023.301 4539.428 600
hybrd.replace_na 1497.8653 1706.1119 1748.464 1745.282 1789.804 2127.166 600
baseR.sbst.rssgn 1480.5098 1686.1581 1730.006 1728.477 1772.951 2010.215 600
baseR.replace 1457.4016 1681.5583 1725.481 1722.069 1766.916 2089.627 600
dplyr_coalesce 1227.6150 1483.3520 1524.245 1519.454 1561.488 1996.859 600
tidyr_replace_na 1248.3292 1473.1707 1521.889 1520.108 1570.382 1995.768 600
hybrd.replace 913.1865 1197.3133 1233.336 1238.747 1276.141 1438.646 600
hybrd.rplc_at.ctn 916.9339 1192.9885 1224.733 1227.628 1268.644 1466.085 600
hybrd.rplc_at.nse 919.0270 1191.0541 1228.749 1228.635 1275.103 2882.040 600
baseR.for 869.3169 1180.8311 1216.958 1224.407 1264.737 1459.726 600
hybrd.rplc_at.idx 839.8915 1189.7465 1223.326 1228.329 1266.375 1565.794 600
DT.for.set.nms 761.6086 915.8166 1015.457 1001.772 1106.315 1363.044 600
DT.for.set.sqln 787.3535 918.8733 1017.812 1002.042 1122.474 1321.860 600
结果示意图ggplot(perf_results, aes(x=expr, y=time/10^9)) +
geom_boxplot() +
xlab('Expression') +
ylab('Elapsed Time (Seconds)') +
scale_y_continuous(breaks = seq(0,7,1)) +
coord_flip()
彩色编码的试验散射图(在对数尺度上有y轴)qplot(y=time/10^9, data=perf_results, colour=expr) +
labs(y = "log10 Scaled Elapsed Time per Trial (secs)", x = "Trial Number") +
coord_cartesian(ylim = c(0.75, 7.5)) +
scale_y_log10(breaks=c(0.75, 0.875, 1, 1.25, 1.5, 1.75, seq(2, 7.5)))
关于其他高表演者的笔记
当数据集变大时,提德‘’replace_na从历史上说是站在前面的。在当前5000万个数据点的集合中,它的性能几乎与基R为了循环。我很想看看不同大小的数据文件会发生什么。
定语和鉴赏
特别感谢:和为了演示微基准。
帮助我理解
local()以及(在弗兰克耐心的帮助下)沉默胁迫在加速这些方法中所起的作用。
亚瑟叶(Arthuryip)为戳添加较新的
coalesce()参与并更新分析。
葛雷格让我去找出
data.table功能足够好,最终包括他们的阵容。
数据表关于循环:
(当然,如果你觉得这些方法有用的话,也请把手伸出来。)
关于我使用数字的注意事项:如果您有一个纯整数数据集,则所有函数都将运行得更快。请看[医]阿列克西兹·拉兹的工作想了解更多信息。IRL,我不记得遇到过包含超过10-15%整数的数据集,所以我在完全数字的数据上运行这些测试。
硬件使用3.9GHz CPU,24 GB RAM