使用data.table为变量组分配NA

时间:2012-12-06 01:45:31

标签: r data.table

我正在尝试使用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_]
}

最佳。

3 个答案:

答案 0 :(得分:2)

这与this question and answer

有关

对于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