在 2015-11-24 完全重写,以修复以前版本中的错误。
还在 2019-09-27 上添加了更多现代选项
你有几个选择。
lapply()
使用对 的嵌入式调用处理所有目标列,用于
:=
在适当位置分配修改后的值。这依赖于:=
对同时分配到其 LHS 上命名的多个列的非常方便的支持。
使用for
循环一次一个地遍历目标列,使用set()
依次修改每一列的值。
使用for
循环迭代多个“天真”调用[.data.table()
,每个调用都修改一个列。
这些方法似乎都同样快,所以你使用哪种方法主要取决于口味。(1) 非常紧凑和富有表现力。这是我最常使用的,尽管您可能会发现 (2) 更易于阅读。因为它们一次处理和修改一个列,所以 (2) 或 (3) 在极少数情况下具有优势,在这种情况下,您的 data.table 太大以至于您有可能遇到 R 施加的限制会话的可用内存。
library(data.table)
## Create three identical 1000000-by-20 data.tables
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)
## Method 1
system.time({
DT1[, .SDcols=cnames[-1L], cnames[-1L] :=
lapply(.SD, function(x) gsub(" ", "_", x, fixed=TRUE)), ]
})
## user system elapsed
## 10.90 0.11 11.06
## Method 2
system.time({
for(cname in cnames[-1]) {
set(DT2, j=cname, value=gsub(" ", "_", DT2[[cname]], fixed=TRUE))
}
})
## user system elapsed
## 10.65 0.05 10.70
## Method 3
system.time({
for(cname in cnames[-1]) {
DT3[ , (cname) := gsub(" ", "_", get(cname), fixed=TRUE)]
}
})
## user system elapsed
## 10.33 0.03 10.37
有关set()
and的更多详细信息:=
,请阅读他们的帮助页面,通过键入?set
or获得?":="
。