【问题标题】:R: Subset by Latest DateR:按最新日期划分的子集
【发布时间】:2014-10-30 08:04:13
【问题描述】:

我有:

Keyword   Date   Pos   Bid
a       4/11/14   1   5.00
a       4/13/14   1   5.00
a       4/14/14   1   5.00
b        6/2/14   3   9.00
b        7/2/14   4   9.00  
b        8/2/14   4   9.00
c       8/29/14   2   3.00
c       8/30/14   2   3.00
c       8/31/14   2   3.00

我需要进行子集化,以便只保留最新日期的行:

Keyword   Date   Pos   Bid
a       4/14/14   1   5.00
b        8/2/14   4   9.00
c       8/31/14   2   3.00

我试过了:

Latest = ddply( df, 
                'Keyword', 
                function(x) c (
                    Date = max(as.Date(x$Date, '%m/%d/%y')), 
                    Pos = x$Pos[which(x$Date == max(as.Date(x$Date, '%m/%d/%y')))], 
                    Bid = x$Bid[which(x$Date == max(as.Date(x$Date, '%m/%d/%y')))]
                )
         )

Latest = subset( x, 
                 Date = max(as.Date(Date, '%m/%d/%y')), 
                 select = c('Identity', 'Date', 'Round.Avg.Pos.', 'Search.Bid')
         )

但是这些要么给我错误,要么不是我想要的。我错过了什么?

谢谢。

【问题讨论】:

    标签: r subset


    【解决方案1】:

    你可以试试

     library(dplyr)
     library(tidyr)
    
      df %>% 
         mutate(Date=as.Date(Date, format= "%m/%d/%y"))%>% 
         group_by(Keyword) %>%  
         arrange(desc(Date)) %>%
         slice(1)
    
      #   Keyword       Date Pos Bid
      #1       a 2014-04-14   1   5
      #2       b 2014-08-02   4   9
      #3       c 2014-08-31   2   3
    

    或者

       df %>% 
          group_by(Keyword) %>%
          mutate(Date=as.Date(Date, format= "%m/%d/%y"))%>% 
          filter(Date==max(Date))
    

    或使用base R

      indx <- with(df, ave(as.Date(Date, format="%m/%d/%y"), Keyword, FUN=max))
      df[with(df, as.Date(Date, format='%m/%d/%y')==indx),]
      #  Keyword    Date Pos Bid
      #3       a 4/14/14   1   5
      #6       b  8/2/14   4   9
      #9       c 8/31/14   2   3
    

    或使用ddply

      ddply(df, .(Keyword), function(x) {
                      Date=as.Date(x$Date, '%m/%d/%y')
                      x[Date==max(Date),]})
    
      #  Keyword    Date Pos Bid
      #1       a 4/14/14   1   5
      #2       b  8/2/14   4   9
      #3       c 8/31/14   2   3
    

    数据

    df <- structure(list(Keyword = c("a", "a", "a", "b", "b", "b", "c", 
     "c", "c"), Date = c("4/11/14", "4/13/14", "4/14/14", "6/2/14", 
     "7/2/14", "8/2/14", "8/29/14", "8/30/14", "8/31/14"), Pos = c(1L, 
    1L, 1L, 3L, 4L, 4L, 2L, 2L, 2L), Bid = c(5, 5, 5, 9, 9, 9, 3, 
    3, 3)), .Names = c("Keyword", "Date", "Pos", "Bid"), class = "data.frame", row.names = c(NA, 
    -9L))
    

    【讨论】:

    • @jazzurro 这是基于您之前的解决方案。
    • 是的,我可以看到。 :)
    • 可能在分组前变异?
    【解决方案2】:

    或使用data.table

    library(data.table)
    setDT(df)[ ,.SD[which.max(as.Date(Date, format= "%m/%d/%y"))], by = Keyword]
    #    Keyword    Date Pos Bid
    # 1:       a 4/14/14   1   5
    # 2:       b  8/2/14   4   9
    # 3:       c 8/31/14   2   3
    

    这是使用“split-apply-combine”方法的其他基本 R 解决方案

    do.call(rbind, lapply(split(df, df$Keyword), 
            function(x) x[which.max(as.Date(x$Date, format='%m/%d/%y')), ]))
    #   Keyword    Date Pos Bid
    # a       a 4/14/14   1   5
    # b       b  8/2/14   4   9
    # c       c 8/31/14   2   3
    

    注意:您想要的输出将Date 列保留为与以前相同的格式,因此我在两种解决方案的每次迭代中都应用as.Date,而最佳 做法是转换它到Date类一次,然后在聚合过程中使用已经转换的列

    【讨论】:

      【解决方案3】:

      试试:

      ddf$Date = as.Date(ddf$Date, format("%m/%d/%y"))
      ddf= ddf[rev(order(ddf$Date)),]
      ddf = ddf[!duplicated(ddf$Keyword),]
      ddf[order(ddf$Keyword),]
        Keyword       Date Pos Bid
      3       a 2014-04-14   1   5
      6       b 2014-08-02   4   9
      9       c 2014-08-31   2   3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-16
        • 1970-01-01
        • 1970-01-01
        • 2016-08-12
        • 1970-01-01
        • 2020-08-24
        • 1970-01-01
        相关资源
        最近更新 更多