首页 > 解决方案 > R使用滞后重新编码变量

问题描述

我有数据,参与者可以在四天的时间跨度内每天获得多个数据点。我希望以 1-4 的值重新编码每一天。这可能是我的数据的一个示例子集:

my.df <- read.table(text="
ID Date  Variable
1  0401  9
1  0402  2
1  0403  5
1  0404  8
2  0402  1
2  0402  9
2  0403  0
2  0404  3
2  0405  2
2  0405  1", header=TRUE)

> dput(my.df)
structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), 
    Date = c(401L, 402L, 403L, 404L, 402L, 402L, 403L, 404L, 405L, 
    405L), Variable = c(9L, 2L, 5L, 8L, 1L, 9L, 0L, 3L, 2L, 1L
    )), .Names = c("ID", "Date", "Variable"), class = "data.frame", 
row.names = c(NA, -10L))

这是我想要的输出:

ID Date  Variable DateRecode 
1  0401  9     1
1  0402  2     2
1  0403  5     3
1  0404  8     4
2  0402  1     1
2  0402  9     1
2  0403  0     2
2  0404  3     3
2  0405  2     4
2  0405  1     4", header=TRUE)

我想我需要使用延迟函数来创建 DateRecode 列,因为真实数据集中有几十个参与者。

我可以使用 dplyr 生成滞后列:

library(dplyr)
my.df <- 
  my.df %>%
  group_by(ID) %>%
  mutate(lag.value = dplyr::lag(Date, n = 1, default = NA))

但这当然不会告诉 R 重新编码任何东西。

我基本上遵循的逻辑是:当按 ID 分组时,如果 Date 的值等于 Date 的第一个/最小值,则创建一个值为 1 的新列。对于每个后续行,如果 Date 是与上一行相同的值,则加 1,否则加 1。

IF 语句也不适用于我。我一直无法找到一种方法来解释每个参与者的日期与上一个参与者不同的事实,所以我希望有一个使用延迟的解决方案。

有人对我如何做这件事有任何建议吗?这几天我一直在为此挠头。提前致谢!

标签: r

解决方案


我们可以做到这一点match

library(dplyr)
my.df %>% 
   group_by(ID) %>% 
   mutate(lag.value = match(Date, unique(Date)))
# A tibble: 10 x 4
# Groups:   ID [2]
#      ID  Date Variable lag.value
#   <int> <int>    <int>     <int>
# 1     1   401        9         1
# 2     1   402        2         2
# 3     1   403        5         3
# 4     1   404        8         4
# 5     2   402        1         1
# 6     2   402        9         1
# 7     2   403        0         2
# 8     2   404        3         3
# 9     2   405        2         4
#10     2   405        1         4

或使用factor并强制它integer

my.df  %>%
  group_by(ID) %>%
  mutate(lag.value = as.integer(factor(Date)))

或者另一种选择是group_indices

library(purrr)
my.df %>% 
  split(.$ID) %>%
  map_df(~ .x %>% mutate(lag.value = group_indices(., Date)))
#   ID Date Variable lag.value
#1   1  401        9         1
#2   1  402        2         2
#3   1  403        5         3
#4   1  404        8         4
#5   2  402        1         1
#6   2  402        9         1
#7   2  403        0         2
#8   2  404        3         3
#9   2  405        2         4
#10  2  405        1         4

注意:这里的“日期”是按顺序排列的。如果不是,则执行arrange,然后执行group_by

my.df %>%
   arrange(ID, Date) %>%
   group_by(ID) %>%
   mutate(lag.value = match(Date, unique(Date)))

推荐阅读