【问题标题】:Calculate the days between dates from a grouped data.frame R dplyr从分组的data.frame R dplyr计算日期之间的天数
【发布时间】:2021-04-28 00:29:19
【问题描述】:

我想通过几个字段来计算一个data.frame的行之间的天数,所以如果我有以下data.frame:

da <- read.table(text="i     j  data date     
 2   682   147 2008-05-26
 2   682   317 2010-11-13
 2   682   217 2019-08-05
 3   682   147 2008-05-26
 3   682   317 2010-11-13
10   682   220 2019-08-08", header=TRUE)
require(dplyr)
da %>% count(i,j)

我想计算第一组的两个周期,第二组一个周期,最后一个周期没有。

我可以计算第一个日期和最后一个日期之间的间隔

require(lubridate)

da %>% group_by(i,j) %>% 
    summarize(fini=ymd(min(date)),fend=ymd(max(date)),deltaD=as.numeric(fend - fini)) 

`summarise()` regrouping output by 'i' (override with `.groups` argument)
# A tibble: 3 x 5
# Groups:   i [3]
      i     j fini       fend       deltaD
  <int> <int> <date>     <date>      <dbl>
1     2   682 2008-05-26 2019-08-05   4088
2     3   682 2008-05-26 2010-11-13    901
3    10   682 2019-08-08 2019-08-08      0

如果我在组中有两行,那很好,但如果我有 3 行或更多,我不知道该怎么做。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    你需要这样的东西吗?

    library(dplyr)
    
    da %>%
      mutate(date = as.Date(date)) %>%
      arrange(i, j, date) %>%
      group_by(i, j) %>%
      transmute(fini = date, fend = lead(date), deltaD = as.numeric(fend - fini)) %>%
      na.omit() %>%
      ungroup
    
    #      i     j fini       fend       deltaD
    #  <int> <int> <date>     <date>      <dbl>
    #1     2   682 2008-05-26 2010-11-13    901
    #2     2   682 2010-11-13 2019-08-05   3187
    #3     3   682 2008-05-26 2010-11-13    901
    

    【讨论】:

    • 稍作修正即可使用deltaD = as.numeric(fend - fini)
    【解决方案2】:

    以下似乎有效。我使用了lead(在arrange 之后按日期排序),并进行了一些调整以避免只有一个日期的组被丢弃

    da %>% 
      group_by(i,j) %>% 
      dplyr::arrange(date) %>% 
      dplyr::mutate(lead_date = dplyr::lead(date),
                    one_in_group = n() == 1) %>% # to maintain row with i = 10
      dplyr::filter(!is.na(lead_date) | one_in_group) %>% 
      dplyr::mutate(lead_date = ifelse(one_in_group, date, lead_date),# handles solo dates
                    date = lubridate::ymd(date),
                    lead_date = lubridate::ymd(lead_date),
                    deltaD = as.numeric(lead_date - date)) %>%
      dplyr::select(- one_in_group) %>% 
      dplyr::arrange(i, j, date)
    
    # A tibble: 4 x 6
    # Groups:   i, j [3]
          i     j  data date       lead_date  deltaD
      <int> <int> <int> <date>     <date>      <dbl>
    1     2   682   147 2008-05-26 2010-11-13    901
    2     2   682   317 2010-11-13 2019-08-05   3187
    3     3   682   147 2008-05-26 2010-11-13    901
    4    10   682   220 2019-08-08 2019-08-08      0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-11
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      • 2015-02-26
      • 2019-09-27
      相关资源
      最近更新 更多