假设dt
是data.table
个对象,其中包含A
,B
和C
列。
我希望在列上循环以过滤掉某些行,然后在该列上应用函数:
for(col in c("A", "B", "C")){
dt[col %in% some_filter[[col], col := some_function(col), with=FALSE]
}
其中some_filter
是包含一些有效值的list
,例如some_filter[["A"]] = c("just", "an", "example")
等。
但是,通过在这4个位置引用col
,data.table
似乎搞乱了命名空间并且失败了。
有一个解决方法是通过临时变量,但如何在一行中执行此任务?
无效的代码是:
library(data.table)
library(dplyr)
dt <- data.table(A=1:10, B=11:20, C=21:30)
f <- list()
f[["A"]] <- 3:5
f[["B"]] <- 14:18
f[["C"]] <- 28:29
for(col in colnames(dt)){
dt[col %in% f[[col]], col := col * 2, with=F] # Double up some rows
}
答案 0 :(得分:3)
我们可以使用get
从包含其名称的字符变量中访问列。在()
的LHS周围:=
也优先使用with = F
for(col in colnames(dt)){
dt[get(col) %in% f[[col]], (col) := get(col) * 2L] # Double up some rows
}
# A B C
# 1: 1 11 21
# 2: 2 12 22
# 3: 6 13 23
# 4: 8 28 24
# 5: 10 30 25
# 6: 6 32 26
# 7: 7 34 27
# 8: 8 36 56
# 9: 9 19 58
# 10: 10 20 30
答案 1 :(得分:1)
另一种选择是使用set
for(nm1 in names(dt)) {
i1 <- which(dt[[nm1]] %in% f[[nm1]])
set(dt, i= i1, j = nm1, value = dt[[nm1]][i1]*2L)
}
dt
# A B C
# 1: 1 11 21
# 2: 2 12 22
# 3: 6 13 23
# 4: 8 28 24
# 5: 10 30 25
# 6: 6 32 26
# 7: 7 34 27
# 8: 8 36 56
# 9: 9 19 58
#10: 10 20 30