【问题标题】:Collapsing daily longitudinal data into monthly observations by ID in R通过 R 中的 ID 将每日纵向数据折叠成每月观察值
【发布时间】:2022-11-19 19:34:15
【问题描述】:

我有纵向数据,每个主题超过 100 行代表日常观察。我想按主题 ID 将列折叠成每月观察值(即每个 ID 有多行,每 30 行(天)数据进行汇总)。

如何使用 dplyr 指定此类天数分组?

同样值得注意的是,所有受试者的总天数都不同

编辑:下面的数据示例

df<-structure(list(ID = structure(c(100087, 100087, 100087, 100087, 
                                    100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 
                                    100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087)), time = structure(c(0, 1, 2, 3, 
                                                                                                                         4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)), 
                   BMI = structure(c(20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 
                                     20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 
                                     20.06, 20.06, 20.06, 20.06, 20.06)), Dis = structure(c(0, 
                                                                                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), 
                   Drug1 = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
                                       1, 1, 1, 1, 1, 1, 1)), Drug2 = structure(c(1, 
                                                                                  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1))), row.names = c(NA, 
                                                                                                                                                            -20L), class = c("tbl_df", "tbl", "data.frame"))

【问题讨论】:

  • 如果您发布任何示例数据,那将非常有帮助 :)
  • 创建一个 month 列作为分组依据。 (也许还有 year 列,如果您的数据跨越多年。)您可以使用 lubridate 函数 month()year() 轻松地从日期中提取月份和年份。如果您需要更多帮助,请提供一些示例数据(使用dput() 使其可复制/粘贴!)和所需的输出。
  • 请使用 dput() 函数分享您的数据样本,以便我们为您提供正确的答案。
  • 我添加了一个数据结构的例子。没有日期,时间列中只有几天

标签: r dplyr longitudinal


【解决方案1】:

我会 group_by ID 和一个新的 times 变量,您可以在其中使用 time %/% 30 指定 30 行的垃圾箱。由于您的示例数据只有几行,因此我将其设置为5。由于每个受访者都有不同数量的times,我们需要记录first_timelast_time,然后将times覆盖为x - y次,其中x和y是第一次和最后一次。

across 调用中,您需要指定聚合数据的方式,下面我选择 mean。如果您想获得 BMImeanDrug1max 值,您需要在单独的函数调用中指定每一列。

library(dplyr)

df %>% 
  group_by(ID, times = time %/% 5) %>% 
  summarise(across(BMI:Drug2, mean),
         time_first = first(time),
         time_last = last(time)
         ) %>% 
  ungroup() %>% 
  mutate(times = paste0(time_first, "-", time_last)) %>% 
  select(-c(time_first, time_last))

#> `summarise()` has grouped output by 'ID'. You can override using the `.groups`
#> argument.
#> # A tibble: 4 × 6
#>       ID times   BMI   Dis Drug1 Drug2
#>    <dbl> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 100087 0-4    20.1     0     1     1
#> 2 100087 5-9    20.1     0     1     1
#> 3 100087 10-14  20.1     0     1     1
#> 4 100087 15-19  20.1     0     1     1

# OPs data
df <- structure(list(ID = structure(c(100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087, 100087)), time = structure(c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)), BMI = structure(c(20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06, 20.06)), Dis = structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), Drug1 = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)), Drug2 = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1))), row.names = c(NA, -20L), class = c("tbl_df", "tbl", "data.frame"))

reprex package (v0.3.0) 创建于 2022-09-27

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多