2

I have a data frame like the following:

library(data.table)
set.seed(1234)
DT<-data.table(x=c("a","a","a","b","b","c","c","c","d","d","d","d"),v=sample(1:4,12,replace = T))

  x v
  a 1
  a 3
  a 3
  b 3
  b 4
  c 3
  c 1
  c 1
  d 3
  d 3
  d 3
  d 3

What I need to do is to replace the value "v" conditionally, each time the variable "x" changes, like so:

      x v
      a 1
      a 3
      a 3
      b NA
      b 4
      c NA
      c 1
      c 1
      d NA
      d 3
      d 3
      d 3

Am I bound to do a loop or there is a one liner to do the same thing? Thanks!

Frank
  • 66,179
  • 8
  • 96
  • 180

1 Answers1

3

Yep, there is a one-liner:

DT[x != shift(x), v := NA]


    x  v
 1: a  1
 2: a  3
 3: a  3
 4: b NA
 5: b  4
 6: c NA
 7: c  1
 8: c  1
 9: d NA
10: d  3
11: d  3
12: d  3

See ?shift and the data.table vignettes for details on this syntax.


Alternately, to avoid computing shift and the full != comparison...

DT[DT[, if (.GRP > 1L) .I[1L], by=rleid(x)]$V1, v := NA ]

following @eddi's approach to subsetting by group. See ?.GRP, ?.I and ?rleid for details.

Community
  • 1
  • 1
Frank
  • 66,179
  • 8
  • 96
  • 180