1

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

最好的。

4

3 回答 3

2

这与这个问题和答案有关

data.table进入使用eval in j模式,整个调用应该是 eval(...)。

否则,您的通话将被解析为

`:=`(eval(parse(text=char)), NA_integer_)

当我试图在 j by中使用 eval 时,不会被选中[.data.table。我还没有测试过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出现错误。%

于 2012-12-06T01:54:36.363 回答
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并且是值得的。[[

于 2012-12-06T10:03:10.587 回答
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
于 2012-12-07T02:32:56.027 回答