1

I am trying to assign NA for specific values (0 and 99) to a group of variables (9 variables, from p05_1 to p05_9) using data.table. I don't get any error, but nothing happens when I use this code:

Here a short example:

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_]
}

Best.

sdaza
  • 962
  • 11
  • 29

3 Answers3

2

This is related to this question and answer

For the data.table to kick into use eval in j mode, the whole call should be eval(...).

Otherwise, your call is parsed as

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

Which won't be picked up as I'm trying to use eval in j by [.data.table. I haven't tested for i, but it could be safe to do this anyway

something like

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))]
}

should work. Note I have fudged the call to %in% to avoid sprintf giving an error using % as a regular character.

Community
  • 1
  • 1
mnel
  • 105,872
  • 25
  • 248
  • 242
2

An alternative to the eval(parse(text= route, in this case :

for (n in 1:2) {
    vnam = paste0("v_",n)
    set(dat, which(dat[[vnam]]%in%c(0,99)), vnam, NA_integer_)
}

Note that [[ in base R doesn't take a copy of the column (it's copy-on-write), so that can be a good way to refer to a single column. Looping set and [[ can be worth it if there are a lot of columns (say 10,000+).

Matt Dowle
  • 56,107
  • 20
  • 160
  • 217
0

Here's another alternative using the replace() function:

> 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
Dennis
  • 684
  • 3
  • 3
  • 1
    That's a copy of those columns, though. It doesn't assign. It doesn't really answer the question afaics. @sdaza Did you realise that when you accepted it? – Matt Dowle Dec 09 '12 at 11:17