基于另一个变量的时滞

时间:2017-12-02 02:13:18

标签: r group-by split-apply-combine

假设:

empName

我想到达:

test <- data.frame(Participant= c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3),
                   Day = c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9),
                   Value= c(1:30))

我尝试过以下操作,它允许我对变量进行时滞,但是在整个列中都是如此。我希望根据ParticipantID或Day变量来延迟时间,以便时间延迟返回&#34; NA&#34;当遇到新的参与者号码或Day = 0时:

test <- data.frame(Participant= c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3),
                   Day = c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9),
                   Value= c(1:30),
                   LaggedValue= c("NA", 1,2,3,4,5,6,7,8,9, "NA", 11,12,13,14,15,16,17,18,19, "NA", 21,22,23,24,25,26,27,28,29))

我不确定如何添加&#34; if&#34;声明或基于参与者/日变量。 nest()函数可能在这里工作吗?

3 个答案:

答案 0 :(得分:0)

要拆分组变量,dplyr库(或by command)就是您所需要的,如下所示(我现在无法访问R解释器):

require(dplyr)
test %>%
    group_by(Participant) %>%
    do(LaggedValue = lag(Value)) %>%
    ungroup()

这个范例是众所周知的split-apply-combine。不要试图用if语句来破解它。

编辑:或data.table包,根据Gary的回答

答案 1 :(得分:0)

使用data.table包,您可以使用特殊的.I内置变量快速执行此操作:

library(data.table)
test <- data.frame(Participant= c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3),
                   Day = c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9),
                   Value= c(1:30))

# convert dataframe to data.table
test_dt <- as.data.table(test)

# Now insert your lagged value and NAs - if new participant
test_dt[, LaggedValue := c(NA, .I[-1] - 1), by = Participant]

# And just in case you misse da day 0
test_dt[Day == 0, LaggedValue := NA]

# Or in a single step based on @thelatemail's comment below
test_dt[, LaggedValue := shift(Value), by=Participant]

这给出了答案:

test_dt

    Participant Day Value LaggedValue
 1:           1   0     1          NA
 2:           1   1     2           1
 3:           1   2     3           2
 4:           1   3     4           3
 5:           1   4     5           4
 6:           1   5     6           5
 7:           1   6     7           6
 8:           1   7     8           7
 9:           1   8     9           8
10:           1   9    10           9
11:           2   0    11          NA
12:           2   1    12          11
13:           2   2    13          12
14:           2   3    14          13
15:           2   4    15          14
16:           2   5    16          15
17:           2   6    17          16
18:           2   7    18          17
19:           2   8    19          18
20:           2   9    20          19
21:           3   0    21          NA
22:           3   1    22          21
23:           3   2    23          22
24:           3   3    24          23
25:           3   4    25          24
26:           3   5    26          25
27:           3   6    27          26
28:           3   7    28          27
29:           3   8    29          28
30:           3   9    30          29
    Participant Day Value LaggedValue

答案 2 :(得分:0)

让我们把它分解为你的要求 -

1)您需要滞后列,因此不要使用 R中的内置滞后(),因为这样做几次相互矛盾的结果。我建议使用HmiSc 包中的 Lag()(以大写字母L开头)来执行此操作。

2)问题的第二部分说明应根据参与者专栏进行滞后。这是一种分组操作,因此数据表以漂亮的方式完成此操作。代码的最后一行显示括号内的by作为分组的意思。最好的部分是这个操作本身就是数据表的结果,所以不需要转换成数据表或数据框,如果你使用 dplyr

所以代码可以是 -

library(data.table)
library(Hmisc)

test <- data.table(Participant= c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3),Day = c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9),Value= c(1:30))

test[,LaggedValue:=Lag(Value),by='Participant']