我正在尝试使用data.table将特定值(0和99)的NA分配给一组变量(9个变量,从p05_1到p05_9)。我没有收到任何错误,但是当我使用这段代码时没有任何反应:
这是一个简短的例子:
v_1 <- c(0,0,1,2,3,4,4,99)
v_2 <- c(1,2,2,2,3,99,1,0)
dat <- data.table(v_1,v_2)
for(n in 1:9) {
char <- sprintf('p05_%s', n)
st[eval(parse(text=char)) %in% c(0,99), eval(parse(text=char)) := NA_integer_]
}
最佳。
答案 0 :(得分:2)
对于data.table
启用eval in j
模式,整个调用应为eval(...)。
否则,您的电话会被解析为
`:=`(eval(parse(text=char)), NA_integer_)
我试图在[.data.table
的j 中使用eval。
我没有测试过i
,但无论如何都可以安全地进行此操作
类似
for(n in 1:2) {
chari <- paste0(sprintf('v_%s' ,n), ' %in% c(0,99)')
charj <- sprintf('v_%s := NA_integer_', n)
dat[eval(parse(text=chari)), eval(parse(text=charj))]
}
应该有效。注意我已将%in%
的来电捏造,以避免sprintf
使用%
作为常规字符时出错。
答案 1 :(得分:2)
eval(parse(text=
路线的替代方案,在这种情况下:
for (n in 1:2) {
vnam = paste0("v_",n)
set(dat, which(dat[[vnam]]%in%c(0,99)), vnam, NA_integer_)
}
请注意,基本R中的[[
不会获取列的副本(它是写时复制),因此这是引用单个列的好方法。如果有很多列(比如10,000 +),循环set
和[[
可能是值得的。
答案 2 :(得分:0)
这是使用replace()函数的另一种替代方法:
> dat[, lapply(list(v_1, v_2), function(x) replace(x, x %in% c(0, 99), NA_integer_))]
V1 V2
1: NA 1
2: NA 2
3: 1 2
4: 2 2
5: 3 3
6: 4 NA
7: 4 1
8: NA NA