【问题标题】:How to find the range of dates for each group in a dataframe如何查找数据框中每个组的日期范围
【发布时间】:2020-12-17 18:20:54
【问题描述】:

考虑这个数据框:

data <- data.frame(group = rep(letters[1:3], c(4,5,4)),
                Date = as.Date(c("2010-08-09", "2010-09-11", "2010-09-12", "2010-09-18",
                                 "2014-03-15","2014-03-16","2014-03-20","2014-03-21","2014-03-25",
                                 "2016-05-02","2016-08-02","2016-08-03","2016-09-21")))

我们有三个小组,他们在不同的日期进行了观察。我想找到每个组的第一个和最后一个日期(最好使用dplyr)。日期如何做到这一点?

编辑: 我添加这个是为了澄清我询问的原因,这与 R 解释实时(日期)的能力有关。 data2 将与上面的 data 完全相同,但请注意我切换了前两个日期,因此 group==a 的观察不再按实际时间顺序排列(从最早到最新,相对于实时):

data2 <- data.frame(group = rep(letters[1:3], c(4,5,4)),
                Date = as.Date(c("2010-09-11","2010-08-09", "2010-09-12", "2010-09-18",
                                 "2014-03-15","2014-03-16","2014-03-20","2014-03-21","2014-03-25",
                                 "2016-05-02","2016-08-02","2016-08-03","2016-09-21")))

因此,2010 年 9 月 11 日在 2010 年 8 月 9 日(实时)之后,但它们在数据框中的时间顺序不同。 现在如果我们这样做:

library(dplyr)
data2%>%group_by(group) %>% summarise(FirsDate=first(Date),LastDate=last(Date))

我们得到:

  group FirsDate   LastDate  
  <fct> <date>     <date>    
1 a     2010-09-11 2010-09-18
2 b     2014-03-15 2014-03-25
3 c     2016-05-02 2016-09-21

所以它返回了第一个和最后一个观察结果,而不是真正的时间顺序。

【问题讨论】:

    标签: r date dplyr summarize


    【解决方案1】:

    我建议使用dplyr 包中的first()last() 函数:

    library(dplyr)
    #Data
    data <- data.frame(group = rep(letters[1:3], c(4,5,4)),
                       Date = as.Date(c("2010-08-09", "2010-09-11", "2010-09-12", "2010-09-18",
                                        "2014-03-15","2014-03-16","2014-03-20","2014-03-21","2014-03-25",
                                        "2016-05-02","2016-08-02","2016-08-03","2016-09-21")))
    #Code
    data %>% group_by(group) %>% mutate(FirsDate=first(Date),LastDate=last(Date))
    

    输出:

    # A tibble: 13 x 4
    # Groups:   group [3]
       group Date       FirsDate   LastDate  
       <fct> <date>     <date>     <date>    
     1 a     2010-08-09 2010-08-09 2010-09-18
     2 a     2010-09-11 2010-08-09 2010-09-18
     3 a     2010-09-12 2010-08-09 2010-09-18
     4 a     2010-09-18 2010-08-09 2010-09-18
     5 b     2014-03-15 2014-03-15 2014-03-25
     6 b     2014-03-16 2014-03-15 2014-03-25
     7 b     2014-03-20 2014-03-15 2014-03-25
     8 b     2014-03-21 2014-03-15 2014-03-25
     9 b     2014-03-25 2014-03-15 2014-03-25
    10 c     2016-05-02 2016-05-02 2016-09-21
    11 c     2016-08-02 2016-05-02 2016-09-21
    12 c     2016-08-03 2016-05-02 2016-09-21
    13 c     2016-09-21 2016-05-02 2016-09-21
    

    如果您只想要每个组的变量,您可以使用summarise()

    #Code2
    data %>% group_by(group) %>% summarise(FirsDate=first(Date),LastDate=last(Date))
    

    输出:

    # A tibble: 3 x 3
      group FirsDate   LastDate  
      <fct> <date>     <date>    
    1 a     2010-08-09 2010-09-18
    2 b     2014-03-15 2014-03-25
    3 c     2016-05-02 2016-09-21
    

    更新:

    #Code
    data2 %>% group_by(group) %>% summarise(FirsDate=min(Date),LastDate=max(Date))
    

    输出:

    # A tibble: 3 x 3
      group FirsDate   LastDate  
      <fct> <date>     <date>    
    1 a     2010-08-09 2010-09-18
    2 b     2014-03-15 2014-03-25
    3 c     2016-05-02 2016-09-21
    

    【讨论】:

    • 所以如果我理解正确,只要数据是班级日期,R 已经知道如何正确按日期排序。它是否正确?很明显,如果您按group 分组,并找到第一个和最后一个观察值,它们也会有第一个和最后一个Date,按实际时间顺序,因为这是我碰巧创建它们的方式。但是,如果您将其应用于观察可能不是“真实”时间顺序的数据帧,R 是否仍然知道找到与实时相关的第一个和最后一个(即最早和最新)Date
    • @Ryan 是的,你是对的!你只需要你的变量是上课日期。
    • 我实际上发现这不起作用,请查看我更新的问题
    • @Ryan 我已经为答案添加了更新!请检查并让我知道这是否有效。我认为最好使用min()max() 函数来同化时代!
    【解决方案2】:

    你可以尝试另一种方式

    library(dplyr)
    data2 <- data %>% 
      group_by(group) %>% 
      filter(row_number()==1 | row_number()==n()) %>% 
      ungroup()
    #   group Date      
    # <chr> <date>    
    # 1 a     2010-08-09
    # 2 a     2010-09-18
    # 3 b     2014-03-15
    # 4 b     2014-03-25
    # 5 c     2016-05-02
    # 6 c     2016-09-21
    

    【讨论】:

      猜你喜欢
      • 2021-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-04
      • 1970-01-01
      相关资源
      最近更新 更多