【问题标题】:Select minimum data of grouped data - keeping all columns [duplicate]选择分组数据的最小数据 - 保留所有列[重复]
【发布时间】:2015-10-29 13:15:16
【问题描述】:

我在这里撞墙了。

我有一个dataframe,有很多行。 这是示意图示例。

#myDf
ID    c1    c2    myDate
A     1     1     01.01.2015
A     2     2     02.02.2014
A     3     3     03.01.2014
B     4     4     09.09.2009
B     5     5     10.10.2010
C     6     6     06.06.2011
....

我需要将我的dataframe 按我的ID 分组,然后选择日期最早的行,并将输出写入一个新的数据框 - 保留所有行。

ID    c1    c2    myDate
A     3     3     03.01.2014
B     4     4     09.09.2009
C     6     6     06.06.2011
....

我就是这样处理的:

test <- myDf %>%
    group_by(ID) %>%
    mutate(date == as.Date(myDate, format = "%d.%m.%Y")) %>%
    filter(date == min(b2))

验证:我生成的数据框的nrow 应该与返回的unique 相同。

unique(myDf$ID) %>% length == nrow(test)

错误

不起作用。我试过这个:

newDf <- ddply(.data = myDf,
              .variables = "ID",
              .fun = function(piece){
                  take.this.row <- piece$myDate %>% as.Date(format="%d.%m.%Y") %>% which.min
                  piece[take.this.row,]
                  })

这确实会永远运行。我终止了它。

为什么第一种方法不起作用?解决问题的好方法是什么?

【问题讨论】:

    标签: r dplyr plyr


    【解决方案1】:

    考虑到您有一个相当大的数据集,我认为使用 data.table 会更好!这是解决您问题的data.table版本,它会比dplyr包更快:

    library(data.table)
    df <- data.table(ID=c("A","A","A","B","B","C"),c1=1:6,c2=1:6,
                     myDate=c("01.01.2015","02.02.2014",
                              "03.01.2014","09.09.2009","10.10.2010","06.06.2011"))
    df[,myDate:=as.Date(myDate, '%d.%m.%Y')]
    
    > df_new <- df[ df[, .I[myDate == min(myDate)], by=ID]$V1 ]
    > df_new
       ID c1 c2     myDate
    1:  A  3  3 2014-01-03
    2:  B  4  4 2009-09-09
    3:  C  6  6 2011-06-06
    

    PS:您可以使用 setDT(mydf) 将 data.frame 转换为 data.table。

    【讨论】:

    • .SD 尚未针对此类子集进行优化。所以,你必须这样做:df[ df[, .I[...], by=ID]$V1 ] 代替.. 这将在下一个最大版本中处理。
    • 感谢您的建议@Arun!我已经重新编辑了答案。
    【解决方案2】:

    通过'ID'分组后,我们可以使用which.min获取'myDate'的索引(转换为Date类后),我们提取slice的行。

    library(dplyr)
    df1 %>% 
       group_by(ID) %>% 
       slice(which.min(as.Date(myDate, '%d.%m.%Y')))
    #     ID    c1    c2     myDate
    #  (chr) (int) (int)      (chr)
    #1     A     3     3 03.01.2014
    #2     B     4     4 09.09.2009
    #3     C     6     6 06.06.2011
    

    数据

    df1 <- structure(list(ID = c("A", "A", "A", "B", "B", "C"), c1 = 1:6, 
    c2 = 1:6, myDate = c("01.01.2015", "02.02.2014", "03.01.2014", 
    "09.09.2009", "10.10.2010", "06.06.2011")), .Names = c("ID", 
    "c1", "c2", "myDate"), class = "data.frame", row.names = c(NA, 
     -6L))
    

    【讨论】:

    • 让我想起了stackoverflow.com/q/31549898/1191259(你给了我group_by(g) %&gt;% slice(which.max(x)) 方法)。你觉得是骗子吗?
    • @Frank 这几乎是一个骗局,但在这里我在slice 中执行as.Date 步骤。如果您想以骗子的身份关闭,欢迎您。
    • 好的。我认为将它们联系起来就足够了。任何人都可以在这里进行欺骗,如果他们想稍后再进行。
    【解决方案3】:

    如果您只想使用基本函数,也可以使用聚合和合并函数。

    # data (from response above)
    
    df1 <- structure(list(ID = c("A", "A", "A", "B", "B", "C"), c1 = 1:6, 
                      c2 = 1:6, myDate = c("01.01.2015", "02.02.2014", "03.01.2014", 
                                           "09.09.2009", "10.10.2010", "06.06.2011")),
                 .Names = c("ID","c1", "c2", "myDate"),
                 class = "data.frame", row.names = c(NA,-6L))
    
    # convert your date column to POSIXct object
    
    df1$myDate = as.POSIXct(df1$myDate,format="%d.%m.%Y")
    
    # Use the aggregate function to look for the minimum dates by group. 
    # In this case our variable of interest in the myDate column and the
    # group to sort by is the "ID" column.
    # The function will sort out the minimum date and create a new data frame
    # with names "myDate" and "ID"
    
    df2 = aggregate(list(myDate = df1$myDate),list(ID = df1$ID),
                function(x){x[which(x == min(x))]})
    
    df2
    
    # Use the merge function to merge your original data frame with the
    # data from the aggregate function
    
    merge(df1,df2)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-21
      • 2019-01-06
      相关资源
      最近更新 更多