在 R 中:创建一个仅包含连续观测值的数据框和一个指示序列号的变量

Posted

技术标签:

【中文标题】在 R 中:创建一个仅包含连续观测值的数据框和一个指示序列号的变量【英文标题】:In R: Create a data frame which includes consecutive observations only and a variable indicating sequence number 【发布时间】:2021-03-01 14:05:54 【问题描述】:

我有一个列名类似于下面的数据框,其中每一行都是一个观察值: 用户身份;日期;变量_1; Var_2

对于每个日期,每个 user_id 可以有 0 或 1 个观察值。每个用户的数据框中只包含有观察的日期。

根据这些数据,我想创建一个包含这些变量(以及下面描述的变量)的数据框,但它应该只包含 3 个连续日期的观察结果(对于每个用户)。每个连续的天数应该从 1 到 3 编号,并且每个连续也应该编号。

例如,如果 user_id == 1 的用户在以下日期有观察:2020-01-01、2020-01-03、2020-01-04、2020-01-05、2020-01-06、2020 -01-10、2020-01-12、2020-01-13、2020-01-14。 user_id == 2 的用户在以下日期有观察结果:2020-01-01、2020-01-03、2020-01-04、2020-01-06、2020-01-10、2020-01-12、 2020-01-15、2020-01-16、2020-01-17

那么新的数据框应该包括:

user_id      日期      序列      天      Var_1      Var_2       1           20-01-03      1                  1                               1            20-01-04      1                  2            价值            价值       1           20-01-05      1                  3                              1           20-01-04      2                  1                              1            20-01-05      2                  2                              1            20-01-06      2                  3            价值           价值       1            20-01-12      3                  1                              1            20-01-13      3                  2                               1            20-01-14      3                  3                              2           20-01-15      1                  1                              2            20-01-16      1                  2                               2            20-01-17      1                  3                              

(其中 value 是变量的观察值)

感谢您对这个棘手问题的帮助!

最好的祝愿, 埃里克

【问题讨论】:

请使用dput 或我们可以复制和使用的东西添加数据。还显示共享数据的预期输出。了解how to ask a good question 和how to give a reproducible example。 【参考方案1】:

这是您可以尝试使用的东西。我确信有比这更好的方法,但它似乎有效。

通过识别作为 3 天序列开始的行进行过滤。为此,请计算日期之间的差异 diff,并确定随后两行的 diff 为一天的日期。

知道序列的开始日期后,您可以将其枚举为sequence。然后,使用map 根据这些开始日期扩展为 3 天序列。之后,您可以在将user_idsequence 分组后再次枚举day

最后,将结果加入到您的原始数据中以获得您的Var_1Var_2 等。

library(dplyr)
library(tidyr)

df %>%
  select(user_id, date) %>%
  group_by(user_id) %>%
  mutate(diff = c(0, diff(date))) %>%
  filter((lead(diff, 1L) == 1 & lead(diff, 2L) == 1)) %>%
  mutate(sequence = row_number(),
         date = map(date, seq.Date, length = 3, by = "1 day")) %>%
  unnest(cols = date) %>%
  group_by(user_id, sequence) %>%
  mutate(day = row_number()) %>%
  inner_join(df, by = c("user_id", "date")) %>%
  select(-diff)

输出

   user_id date       sequence   day Var_1 Var_2
     <dbl> <date>        <int> <int> <int> <int>
 1       1 2020-01-03        1     1     2    17
 2       1 2020-01-04        1     2     3    16
 3       1 2020-01-05        1     3     4    15
 4       1 2020-01-04        2     1     3    16
 5       1 2020-01-05        2     2     4    15
 6       1 2020-01-06        2     3     5    14
 7       1 2020-01-12        3     1     7    12
 8       1 2020-01-13        3     2     8    11
 9       1 2020-01-14        3     3     9    10
10       2 2020-01-15        1     1    16     3
11       2 2020-01-16        1     2    17     2
12       2 2020-01-17        1     3    18     1

数据

df <- structure(list(user_id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 
2, 2, 2, 2, 2, 2), date = structure(c(18262, 18264, 18265, 18266, 
18267, 18271, 18273, 18274, 18275, 18262, 18264, 18265, 18267, 
18271, 18273, 18276, 18277, 18278), class = "Date"), Var_1 = 1:18, 
    Var_2 = 18:1), class = "data.frame", row.names = c(NA, -18L
))

【讨论】:

嗨 Ben 非常感谢您的贡献,这对您有很大帮助!最良好的祝愿,埃里克

以上是关于在 R 中:创建一个仅包含连续观测值的数据框和一个指示序列号的变量的主要内容,如果未能解决你的问题,请参考以下文章

R语言之创建数据集

如何使用具有超过 2^31 个观测值的 biglm

如何在处理 r 中超过 500 万个观测值的数据框时加快迭代速度?

第2章--创建数据集

对于表中的每个观测值,根据纬度和经度 (R) 计算 x 米内的表中其他观测值的数量

在 C# 中使用 Linq 创建一个仅包含唯一值的 DataTable