在2015-11-24完全重写,以修复之前版本中的错误。
还于2019-09-27添加了更现代的选项。
你有几个选择。
使用内嵌调用lapply()
处理所有目标列,使用:=
在原地分配修改后的值。这依赖于:=
非常方便地支持同时分配给其左侧的多个列名。
使用for
循环一次运行一个目标列,使用set()
逐个修改每个值。
使用for
循环遍历多个“naive”调用[.data.table()
,每个调用都修改一个单独的列。
这些方法看起来速度都差不多,所以你使用哪个取决于个人口味。(1)非常精简和表达。我经常使用它,不过你可能会发现(2)更容易阅读。因为它们一次只处理和修改一个列,所以在你的data.table非常大,你有可能会遇到R session可用内存限制的罕见情况下,(2)或(3)将具有优势。
library(data.table)
DT1 <- data.table(1:1e6,
as.data.table(replicate(1e6, paste(sample(letters, nr, TRUE),
sample(letters, nr, TRUE)))))
cnames <- c("ID", paste0("X", 1:19))
setnames(DT1, cnames)
DT2 <- copy(DT1); DT3 <- copy(DT1)
system.time({
DT1[, .SDcols=cnames[-1L], cnames[-1L] :=
lapply(.SD, function(x) gsub(" ", "_", x, fixed=TRUE)), ]
})
system.time({
for(cname in cnames[-1]) {
set(DT2, j=cname, value=gsub(" ", "_", DT2[[cname]], fixed=TRUE))
}
})
system.time({
for(cname in cnames[-1]) {
DT3[ , (cname) := gsub(" ", "_", get(cname), fixed=TRUE)]
}
})
要了解更多关于set()
和:=
的详细信息,请阅读它们的帮助页面,可以通过键入?set
或?":="
获取。
:=
的右侧几乎是整个表格。当添加一两列到20个中或修改20个中的一两列时,:=
的优势更大。在这些情况下,大多数列保持不变,:=
比复制整个表格要快得多。 - Matt Dowleset()
,但还不太有资格讨论它。再次感谢您为data.table软件包的持续发展所做的所有工作! - Josh O'Brienas.data.table(replicate(1e6, paste(sample(letters, nr, TRUE),
sample(letters, nr, TRUE)))))
DT1 <- data.table(1:1e6, as.data.table(replicate(19, paste(sample(letters, 2, TRUE), sample(letters, 2, TRUE)))))
- Konstantinos