【问题标题】:Time interval over multiple rows多行的时间间隔
【发布时间】:2018-01-15 17:25:21
【问题描述】:

我正在尝试解决一个使用时间间隔的问题,这让我很头疼一段时间。

这是两个 ID 的药物处方示例。

df <- data.frame('ID' = c('1','1','1','1','2','2'), 'start' = c('2010-01-01', '2010-01-03', '2010-01-05', '2010-01-09','2010-02-01', '2010-02-10'),
             'end' = c('2010-01-03', '2010-01-22', '2010-01-07', '2010-01-12', '2010-02-10', '2010-02-12'))

  ID      start        end
1  1 2010-01-01 2010-01-03
2  1 2010-01-03 2010-01-22
3  1 2010-01-05 2010-01-07
4  1 2010-01-09 2010-01-12
5  2 2010-02-01 2010-02-10
6  2 2010-02-10 2010-02-12

目的是创建一个新的列来指示持续吸毒。所以在这个例子中,两个 ID 都有连续使用(处方结束和下一个处方开始之间的最大间隔 = 1 天)。最终结果应该是这样的(逻辑上表示连续使用):

  ID      start        end  continuous
1  1 2010-01-01 2010-01-03 FALSE
2  1 2010-01-03 2010-01-22 TRUE
3  1 2010-01-05 2010-01-07 TRUE
4  1 2010-01-09 2010-01-12 TRUE
5  2 2010-02-01 2010-02-10 FALSE
6  2 2010-02-10 2010-02-12 TRUE

我尝试使用 dplyr 和 lubridate 解决此问题,但未能获得第 4 行的正确结果,因为第 3 行不是连续的,而是第 2 行。这是我的代码:

df$start <- ymd(df$start)
df$end <- ymd(df$end)
df <- df %>% group_by(ID) %>% mutate(continuous = if_else(lag(end) - start >= -1, TRUE, FALSE, missing = FALSE))

我非常感谢您对此的帮助!谢谢!

【问题讨论】:

    标签: r time intervals overlap


    【解决方案1】:

    按 ID 将数据帧分组,然后检查每一行的开始是否位于另一行的开始和结束之间。 (它总是位于自身的开始和结束之间,因此,如果sum(..)&gt;1,则返回TRUE

    数据:

    df <- data.frame('ID' = c('1','1','1','1','2','2'), 'start' = c('2010-01-01', '2010-01-03', '2010-01-05', '2010-01-09','2010-02-01', '2010-02-10'),
                     'end' = c('2010-01-03', '2010-01-22', '2010-01-07', '2010-01-12', '2010-02-10', '2010-02-12'),stringsAsFactors = F)
    df$start = as.Date(df$start)
    df$end = as.Date(df$end)
    

    代码:

    df$continuous = unlist(lapply(split(df,df$ID), function(x) {lapply(1:nrow(x), 
                 function(y) { sum(x$start[y]>=x$start & x$start[y] <= x$end + 1) })>1  }))
    

    输出:

      ID      start        end continuous
    1  1 2010-01-01 2010-01-03      FALSE
    2  1 2010-01-03 2010-01-22       TRUE
    3  1 2010-01-05 2010-01-07       TRUE
    4  1 2010-01-09 2010-01-12       TRUE
    5  2 2010-02-01 2010-02-10      FALSE
    6  2 2010-02-10 2010-02-12       TRUE
    

    希望这会有所帮助!

    【讨论】:

    • 我很困惑并删除了我的答案。尝试在此数据框df1 &lt;- rbind(data.frame(ID = 1, start = as.POSIXct(c('2010-02-03', '2010-02-05'), format = '%Y-%m-%d'), end =as.POSIXct(c('2010-02-04', '2010-02-06'), format = '%Y-%m-%d'), stringsAsFactors = F), df[df$ID == 2,]) 上运行您的解决方案,这是预期的结果吗?
    • 太棒了!非常感谢弗洛里安!
    • @Sotos,您是对的,感谢您的提醒。我忘了包括 1 天的间隔,我会更新我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 2019-01-07
    • 2021-08-21
    相关资源
    最近更新 更多