带有组条件的滞后R data.table

时间:2019-03-05 22:26:52

标签: r data.table

我有这样的数据:

test <- data.frame(id = c(1,2,1,5,5,5,6),
               time = c(0,1,4,5,6,7,9),
               cond = c("a","a","b","a","b","b","b"),
               value = c(5,3,2,4,0,3,1), 
               stringsAsFactors=F)

setDT(test)[,order := order(time),id][order(id,order)]

id time cond value order
1  0    a    5     1
2  1    a    3     1
1  4    b    2     2
5  5    a    4     1
5  6    b    0     2
5  7    b    3     3
6  9    b    1     1

data.table函数创建一个“ order”列,它是基于组ID的时间顺序。

我想创建一个返回前一个值但仅在条件为“ b”的列。如果条件为“ a”,则返回当前值;如果条件为“ b”,而前一个条件为“ b”,则跳至下一个非“ b”。如果组的第一个条件是“ b”,则返回NA。

所需的输出如下:

id time cond value order prev
1  0    a    5     1     5
2  1    a    3     1     3
1  4    b    2     2     5
5  5    a    4     1     4
5  6    b    0     2     4
5  7    b    3     3     4
6  9    b    1     1     NA

我已经尝试过一些类似的功能,但是只返回了NA。

test[, prev := shift(value[cond == 'b']), .(id,order)]

2 个答案:

答案 0 :(得分:2)

如果我对问题的理解正确,那么一种选择可能是:

library(data.table)

setDT(test)[, order := order(time), id][order(id, order)]

test[, prev := {
  frst <- ifelse(cond[1] == "a", value[1],
                 ifelse(cond[1] == "b", NA, cond[1]))

  prev <- as.integer(ifelse(cond == "b" & shift(cond) == "b",
                            NA,
                            c(frst, shift(value)[-1])))

}, by = id][cond == "b", prev := zoo::na.locf(prev), by = id]

输出:

   id time cond value order prev
1:  1    0    a     5     1    5
2:  1    4    b     2     2    5
3:  2    1    a     3     1    3
4:  5    5    a     4     1    4
5:  5    6    b     0     2    4
6:  5    7    b     3     3    4
7:  6    9    b     1     1   NA

答案 1 :(得分:0)

如果您先分配非b值,则zoo:na.locf可以完成其余工作(向下填充b(NA)值)。

library(zoo)
test[cond != 'b', prev := value]
test[, prev := na.locf(prev), id]

test
#    id time cond value order prev
# 1:  1    0    a     5     1    5
# 2:  2    1    a     3     1    3
# 3:  1    4    b     2     2    5
# 4:  5    5    a     4     1    4
# 5:  5    6    b     0     2    4
# 6:  5    7    b     3     3    4
# 7:  6    9    b     1     1   NA