r - 在 R 中,使用 Lubridate 获取事件之间的条件平均持续时间

标签 r date dplyr lubridate

背景

我有一个数据框d:

d <- data.frame(ID = c("a","a","a","a","a","a","a","b","b","c","c"),
                treatment = c(0,1,0,0,0,1,0,1,0,1,1),
                #event = c(0,0,1,1,1,1,1,0,1,1,1),
                service_date = as.Date(c("2011-01-01",   
                                         "2011-08-21",   
                                         "2011-12-23",   
                                         "2012-02-23",   
                                         "2013-09-14",   
                                         "2013-04-07",   
                                         "2014-10-14",   
                                         "2013-01-01",
                                         "2013-12-12",   
                                         "2014-06-17",
                                         "2015-09-29")), 
                stringsAsFactors=FALSE)

> d
   ID treatment service_date
1   a         0   2011-01-01
2   a         1   2011-08-21
3   a         0   2011-12-23
4   a         0   2012-02-23
5   a         0   2013-09-14
6   a         1   2013-04-07
7   a         0   2014-10-14
8   b         1   2013-01-01
9   b         0   2013-12-12
10  c         1   2014-06-17
11  c         1   2015-09-29

它描述了一些人 (ID),他们是否接受过治疗,以及每个条目的日期(行)。

问题

我想为 ID 计算第一个和最后一个 treatment==1 之间的平均持续时间,其中 treatment==1

为了更清楚地说明这一点,让我们像手动执行此操作一样布置步骤,并查看我想要的答案:

  1. ID 一个。 A先生有7行数据,但只有两行treatment==1:一行来自2011-08-21(第2行),另一行来自2013-09-14(第6行) .如果您手算差值,您会发现两者之间相差 595 天。

  2. 对于 ID b,我们什么都不做,因为他们只有 1 个 treatment==1。 (我们将使用 filter 来跳过代码中像 b 这样的人。)

  3. 对于 c 先生,我们得到 469 天的差异。

  4. 该组的平均治疗时间:(595 天 + 469 天)/2 人 = 532 天。这是期望的结果。

(我完全有可能做错了这个手工计算,这很好,只要它足以理解我正在尝试做的事情。如果需要,很乐意进一步澄清;让我知道!)

我尝试过的

我正在尝试从类似的查询中改编一些旧代码来解决这个问题:

d %>%
  group_by(ID) %>%
  filter(sum(treatment) >1) %>%
  mutate(treatment_years = lubridate::time_length(max(service_date) - min(service_date), unit = "year")) %>%
  ungroup() %>%
  summarise(avg = mean(treatment_years),
            sd = sd(treatment_years))

此代码运行,让我几乎到那里。它过滤掉不需要的 ID 并为每个人在定义的时间间隔内进行均值(和标准差)计算。

但它不太正确:在 lubridate::time_length 中,它没有指定条件“max service date where treatment==1”减去“最小服务日期,其中treatment==1”。 (粗体部分是缺少和需要的部分。)

我怎样才能做到这一点?

我试过类似的东西,但它只是抛出一个错误:

d %>%
  group_by(ID) %>%
  filter(sum(treatment) >1) %>%
  mutate(treatment_years = lubridate::time_length(max(service_date) & treatment==1 - min(service_date) & treatment==1, unit = "year")) %>%
  ungroup() %>%
  summarise(avg = mean(treatment_years),
            sd = sd(treatment_years))

最佳答案

我们可以将 service_date 子集化为逻辑向量 treatment == 1service_date[treatment == 1](假设在至少一个“处理”级别 1)

library(dplyr)
library(lubridate)
d %>%
  group_by(ID) %>%
  filter(sum(treatment) >1) %>%
  summarise(treatment_years = lubridate::time_length(max(service_date[treatment == 1]) - 
                    min(service_date[treatment == 1]), unit = "day"), .groups = 'drop') %>%  
  summarise(avg = mean(treatment_years),
            sd = sd(treatment_years))

-输出

# A tibble: 1 × 2
    avg    sd
  <dbl> <dbl>
1   532  89.1

关于r - 在 R 中,使用 Lubridate 获取事件之间的条件平均持续时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73462545/

相关文章:

r - 有没有办法在一组预定义变量上运行 dplyr 函数?

r - 错误 : . onLoad 在 'tcltk' 的 loadNamespace() 中失败,详细信息 :call: fun(libname, pkgname)

R Shiny list2env

android - String.format 在德语语言环境中不提供月份和星期名称

azure - 如何更改 Azure DevOps 工作项中工作项的日期格式

r - 如何根据 R 中的条件用字符串替换 NA?

python - 关闭 R Notebook 中的警告

r - ggplot 的自定义换行符

javascript - js-datepicker 日期范围结束基于开始

r - dplyr使用数据框功能进行汇总