【问题标题】:Time Lag based on another variable基于另一个变量的时间延迟
【发布时间】:2017-12-02 02:13:18
【问题描述】:

给定:

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

我想到达:

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

我已经尝试了以下方法,它允许我对变量进行时间滞后,但在整个列中都这样做。我想根据 ParticipantID 或 Day 变量进行时间延迟,这样当遇到新的参与者编号或 Day=0 时,时间延迟会返回“NA”:

test$LaggedValue <- c(NA, test$Value[seq_along(test$Value) -1])

我不确定如何添加“if”语句或基于 Participant/Day 变量。 nest() 函数可能在这里工作吗?

【问题讨论】:

  • 这个范式就是众所周知的split-apply-combine。不要试图用 if 语句来破解它。
  • 您的数据也是长格式的。如果您转换为宽格式,您可能会发现它更简单、更清晰,即使用cast/melt() 以便(比如说)Participant 成为行索引,Day 成为列索引(或 v.v.)。那么lag()就变成了直接对列(/行)的简单操作。您可以阅读相关内容。
  • 这必须是重复的; [r] group_by lag有 739 次点击

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


【解决方案1】:

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

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

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

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

【讨论】:

  • 它有效,但目前使用mutate 而不是do
【解决方案2】:

让我们把它分解成你的要求是什么-

1) 您需要一个 滞后列,因此 不要使用 R 中的内置 lag(),因为这会给出多次出现冲突的结果。我建议使用 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']

【讨论】:

  • data.table 的滞后/领先是 shift
  • 感谢您提供的信息,我不知道。从下次开始我会尝试使用它:)
【解决方案3】:

使用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

【讨论】:

  • data.table 还具有 shift 内置的超前/滞后功能:test_dt[, LaggedValue := shift(Value), by=Participant],这样就无需手动使用.I
猜你喜欢
  • 2017-01-09
  • 2015-10-27
  • 1970-01-01
  • 2019-01-07
  • 2023-01-20
  • 2019-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多