【问题标题】:Subsetting datatable based on consecutive difference of dates基于日期的连续差异子集数据表
【发布时间】:2020-03-22 17:21:48
【问题描述】:

序言: 主要问题是如何根据 ID 对数据表进行子集化,根据连续时间差在 ID 内形成子集。非常欢迎对此提供提示。

完整的问题/设置: 我有一个 data.table 格式的数据集 dt,看起来像

  date       id val1 val2
  %d.%m.%Y
1 01.01.2000  1   5    10
2 09.01.2000  1   4     9
3 01.08.2000  1   3     8
4 01.01.2000  2   2     7
5 01.01.2000  3   1     6
6 14.01.2000  3   7     5
7 28.01.2000  3   8     4
8 01.06.2000  3   9     3

我想合并间隔不超过两周的观察结果(按id 分组)(从观察到观察)。通过组合我的意思是对于每个子集,我

  • 保留val1最后一次观察的值
  • 将最后一次观察的val2 替换为该组val2 的所有值的总和
  • 添加 counter 了解该组中有多少观察结果。

也就是说,我想最终得到这样的数据集

  date       id val1 val2 counter
  %d.%m.%Y
2 09.01.2000  1   4    19       2
3 01.08.2000  1   3     8       1
4 01.01.2000  2   2     7       1
7 28.01.2000  3   8    15       3
8 01.06.2000  3   9     3       1

不过,我仍试图围绕 data.table 函数,尤其是 .SD 函数,并希望使用这些工具解决问题。

目前为止我知道

  • 我可以使用setkey(dt,date) 来说明我所说的第一个和最后一个的意思
  • 我可以用总和替换子集的最后一个val2 dt[, val2 := replace(val2, .N, sum(val2[-.N], na.rm = TRUE)), by=id]
  • 我用[.N] 得到子集的长度
  • 如何删除行
  • 我可以用difftime(strptime(dt$date[1],format ="%d.%m.%Y"),strptime(dt$date[2],format ="%d.%m.%Y"),units="weeks") 计算两个日期之间的差异

但是我不知道如何对观察进行子集化,以使每个子集仅包含相同id 的观察组,并且(连续)距离的日期最长为 2 周。

感谢任何帮助。非常感谢。

【问题讨论】:

    标签: r data-cleaning


    【解决方案1】:

    诀窍是在条件上使用cumsum()。在这种情况下,条件是超过 14 天。当条件为真时,累计和递增。

    df %>%
      mutate(rownumber = row_number()) %>%
      group_by(id) %>%
      mutate(interval = as.numeric(as.Date(date, format = "%d.%m.%Y") - as.Date(lag(date), format = "%d.%m.%Y"))) %>%
      mutate(interval = ifelse(is.na(interval), 0, interval)) %>%
      mutate(group = cumsum(interval > 14) + 1) %>%
      ungroup() %>%
      group_by(id, group) %>%
      summarise(
        rownumber = last(rownumber),
        date = last(date),
        val1 = last(val1),
        val2 = sum(val2),
        counter = n()
      ) %>%
      select(rownumber, date, id, val1, val2, counter)
    

    输出

      rownumber date          id  val1  val2 counter
          <int> <chr>      <int> <int> <int>   <int>
    1         2 09.01.2000     1     4    19       2
    2         3 01.08.2000     1     3     8       1
    3         4 01.01.2000     2     2     7       1
    4         7 28.01.2000     3     8    15       3
    5         8 01.06.2000     3     9     3       1
    

    【讨论】:

    • 感谢您的时间和代码。我想知道是否还有一种方法可以在 data.tables 中进行子集化。我不知道如何将您的 cumsum 解决方案翻译为那里的子集。你有什么建议吗?提前致谢。
    • 我通常不采用数据表方法,因为语法总是更先进,需要更多思考。 dplyr 溶液正常流动。但是,如果您在数据表中有一个工作示例,并且您只需要包含 cumsum(),我可能会尝试为您包含它。
    猜你喜欢
    • 2018-01-26
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2020-05-03
    相关资源
    最近更新 更多