【问题标题】:group_by with which in R在 R 中使用的 group_by
【发布时间】:2016-05-02 03:23:16
【问题描述】:

尝试从数据集创建参考表以查找文档的当前状态。示例如下:

Document<-c(1,1,1,1,2,2,2)
change_date <- c("2015-01-01","2015-01-03","2015-01-05","2015-01-08","2015-01-05","2015-01-07","2015-01-20")
status <- c("A","A","B","C","A","B","D")
df<-data.frame(Document,change_date,status)

基本上决赛桌应该如下所示:

  Document.x status
1          1      C
2          2      D

我目前正在使用下面的代码,但肯定有一种更聪明的方法可以将状态为 date==max(date) 的文档分组?

library(dplyr)
df$change_date <- as.Date(df$change_date)
df1<-group_by(df,Document) %>%
      summarise(latest=max(change_date))
df1$uid<-paste(df1$Document,df1$latest,sep="_")
df$uid<-paste(df$Document,df$change_date,sep="_")
df2<-merge(df1,df,"uid",x.all=TRUE)
df2<-df2[,c(2,6)]

提前致谢。

【问题讨论】:

    标签: r group-by dplyr


    【解决方案1】:

    您可以直接在dplyr中调用max(change_date)

    df %>% 
      group_by(Document) %>% 
      filter(change_date == max(change_date)) %>%
      filter(row_number() == 1) % in case you have duplicate records falling on the last date
    

    【讨论】:

    • 谢谢。从来没有想过过滤器功能..这对这种情况很有意义。
    【解决方案2】:

    我们可以使用'change_date'上的which.max来获取最大日期的索引,并根据'文档'分组后的'状态'子集

    df %>%
       group_by(Document) %>% 
       summarise(status = status[which.max(change_date)])
    #     Document status
    #      (dbl) (fctr)
    #1        1      C
    #2        2      D
    

    或者按Document分组后,我们arrange'change_date'降序,得到每个组的第一行,select只有ungrouping之后的相关列。

    df %>%
      group_by(Document) %>% 
      arrange(desc(change_date)) %>% 
      slice(1L) %>%
      ungroup() %>% 
      select(-change_date)
    #     Document status
    #      (dbl) (fctr)
    #1        1      C
    #2        2      D
    

    使用data.table,语法为

     library(data.table)
     setDT(df)[, .(status = status[which.max(change_date)]), by = Document]
    

    或者base R

     df[with(df, ave(change_date, Document,
                  FUN= max)==change_date), c(1,3)]
    #    Document status
    #4        1      C
    #7        2      D
    

    或者使用sqldf

    library(sqldf)
    sqldf('select Document, status
            from df 
            where change_date in (select max(change_date) from df
            group by "Document")')
    #  Document status
    #1        1      C
    #2        2      D
    

    注意:在 OP 的帖子中,'change_date' 是 factor 类。在尝试上述解决方案之前,应将其转换为 Date 类。

    数据

    df$change_date <- as.Date(df$change_date)
    

    【讨论】:

    • 谢谢!我比较习惯 dplyr,很高兴知道 data.table 作为替代方案!
    • @woshishui 那我不是也提供了简洁的dplyr代码吗?
    • 我对stackoverflow比较陌生,我只能接受其中一个答案,即使它们都是正确的!无论如何要解决这个问题?
    • 如果每个 Document 中只有一个最大 change_date 行,上述解决方案给出了相同的答案。
    • @G.Grothendieck 我还提供了一种解决方案,==
    猜你喜欢
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 2022-06-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2017-06-02
    相关资源
    最近更新 更多