SO #24833247几乎涵盖了将列名动态传递给函数中的data.table
的所有用例。但是它错过了我目前试图解决的问题:将变量传递给i
表达式。
我试图将一些数据清理代码重构为一个函数,在我将数据提取到NA
data.table
例如,给出以下内容:
dt <- data.table(colA = c('A', 'b', '~', 'd', ''), colB = c('', '?', 'a1', 'a2', 'z4'))
dt[colA %in% c('~', ''), colA := NA]
dt[colB %in% c('~', ''), colB := NA]
我想要一个泛型函数,用'~'
替换'?'
,''
和NA
值,而不必显式编码每个转换。
dt <- data.table(colA = c('A', 'b', '~', 'd', ''), colB = c('', '?', 'a1', 'a2', 'z4'))
clearCol(dt, colA)
clearCol(dt, colB)
j
表达式是直截了当的
clearCol <- function(dt, f) {
f = substitute(f)
dt[,(f) := NA]
}
clearCol(data.table(colA = c('A', 'b', '~', 'd', '',)), colA)[]
x
1: NA
2: NA
3: NA
4: NA
5: NA
但是,扩展它以将变量添加到i
表达式失败:
clearCol <- function(dt, f) {
f = substitute(f)
dt[(f) %in% c('~', ''),(f) := NA]
}
clearCol(data.table(colA = c('A', 'b', '~', 'd', '')), colA)[]
Error in match(x, table, nomatch = 0L) : 'match' requires vector arguments
交换到这似乎有效,但是verbose = TRUE
缺少输出(与顶部的硬编码方法相比)让我担心在给定大数据集I&#时它不能很好地扩展39;正在与
clearCol <- function(dt, f) {
f = deparse(substitute(f))
dt[get(f) %in% c('~', ''),(f) := NA]
}
clearCol(data.table(colA = c('A', 'b', '~', 'd', '')), colA)[]
colA
1: A
2: b
3: NA
4: d
5: NA
还有另一种做我想做的事吗?
答案 0 :(得分:1)
您可以follow FAQ 1.6获取详细输出:
cc = function(d, col, vs = c("~", ""), verb = FALSE){
col = substitute(col)
ix = substitute(col %in% vs)
d[eval(ix), as.character(col) := NA, verbose = verb ][]
}
dt <- data.table(colA = c('A', 'b', '~', 'd', ''), colB = c('', '?', 'a1', 'a2', 'z4'))
cc(dt, colA, verb = TRUE)
给出了
Creating new index 'colA'
Starting bmerge ...done in 0 secs
Detected that j uses these columns: <none>
Assigning to 2 row subset of 5 rows
Dropping index 'colA' due to update on 'colA' (column 1)
colA colB
1: A
2: b ?
3: NA a1
4: d a2
5: NA z4
但是,请注意详细输出在这里说的内容。它正在创建一个索引(假设你没有做某事来创建它,这似乎很可能,因为数据只是刚读入)...然后它正在删除该索引(因为它被列的编辑无效) 。这几乎听起来不像是有助于提高效率的东西。
如果你真的想有效地做到这一点,有几个选择:
na.strings
set
醇>