R 按组查找一段时间内的平均值,并检索同一时间段的最后日期

R 按组查找一段时间内的平均值,并检索同一时间段的最后日期,r,dataframe,dplyr,data.table,R,Dataframe,Dplyr,Data.table,以下是四列可复制数据表: 日期 类别 价值1 价值2 正如标题所示,我想计算每个类别value1和value2的平均值,并将这些类别的最后观察日期保留在结果数据框中 以下是输入: # Libraries library(dplyr) library(data.table) # Reproducible data table set.seed(1234) date <- seq(as.Date("2017-01-01"), by = "month", length.out = 10) ca

以下是四列可复制数据表:

  • 日期
  • 类别
  • 价值1
  • 价值2
  • 正如标题所示,我想计算每个类别value1value2的平均值,并将这些类别的最后观察日期保留在结果数据框中

    以下是输入:

    # Libraries
    library(dplyr)
    library(data.table)
    
    # Reproducible data table
    set.seed(1234)
    date <- seq(as.Date("2017-01-01"), by = "month", length.out = 10)
    category <- (c('A','A','B','B','C','C','C','C','C', 'C'))
    value1 <- sample(seq(from = 91, to = 100, by = 1))
    value2 <- sample(seq(from = 51, to = 60, by = 1))
    dt <- data.table(date, category, value1, value2)
    print(dt)
    
              date category value1 value2
     1: 2017-01-01        A     92     57
     2: 2017-02-01        A     96     55
     3: 2017-03-01        B     95     53
     4: 2017-04-01        B     98     60
     5: 2017-05-01        C     99     52
     6: 2017-06-01        C     94     59
     7: 2017-07-01        C     91     56
     8: 2017-08-01        C     97     51
     9: 2017-09-01        C    100     58
    10: 2017-10-01        C     93     54
    
    dt2 <- dt %>% group_by(category) %>% summarise_each(funs(mean))
    print(dt2)
    
    # A tibble: 3 x 4
      category       date   value1 value2
         <chr>     <date>    <dbl>  <dbl>
    1        A 2017-01-16 94.00000   56.0
    2        B 2017-03-16 96.50000   56.5
    3        C 2017-07-16 95.66667   55.0
    
      category       date   value1 value2
    1        A 2017-02-01 94.00000   56.0
    2        B 2017-04-01 96.50000   56.5
    3        C 2017-10-01 95.66667   55.0
    

    谢谢你的建议

    以下是
    数据表
    方法。我们可以使用
    j
    参数在
    ()
    中执行计算,并通过
    参数在
    中设置分组

    dt[, .(date = last(date), value1 = mean(value1), value2 = mean(value2)), by = category]
    
    以下是弗兰克在这篇文章中提出的一种更有效的方法。这种方法只需编写一次
    mean
    函数,使用
    .SD
    .SDcols
    指定要以平均值汇总的列

    dt[, c(.(date = last(date)), lapply(.SD, mean)), by = category, .SDcols = value1:value2]
    
    如果你想使用dplyr,你可以使用Z.Lin的方法。但是,如果有很多值列,例如
    value1
    value10
    ,则可以执行以下操作

    dt %>%
      group_by(category) %>%
      summarise_all(funs(if_else(is.numeric(.), mean(.), last(.))))
    
    此代码仅在列为数字时计算平均值,否则将报告组的最后一行


    最后一个提醒,
    summary\u每个
    都已被弃用。请使用
    summary\u all
    summary\u if
    ,或
    summary\u at

    以下是
    数据表
    方法。我们可以使用
    j
    参数在
    ()
    中执行计算,并通过
    参数在
    中设置分组

    dt[, .(date = last(date), value1 = mean(value1), value2 = mean(value2)), by = category]
    
    以下是弗兰克在这篇文章中提出的一种更有效的方法。这种方法只需编写一次
    mean
    函数,使用
    .SD
    .SDcols
    指定要以平均值汇总的列

    dt[, c(.(date = last(date)), lapply(.SD, mean)), by = category, .SDcols = value1:value2]
    
    如果你想使用dplyr,你可以使用Z.Lin的方法。但是,如果有很多值列,例如
    value1
    value10
    ,则可以执行以下操作

    dt %>%
      group_by(category) %>%
      summarise_all(funs(if_else(is.numeric(.), mean(.), last(.))))
    
    此代码仅在列为数字时计算平均值,否则将报告组的最后一行


    最后一个提醒,
    summary\u每个
    都已被弃用。请使用
    summary\u all
    summary\u if
    ,或
    summary\u at

    这就是你要找的吗

    dt %>%
      group_by(category) %>%
      summarise(date = max(date),
                value1 = mean(value1),
                value2 = mean(value2)) %>%
      ungroup()
    
    # A tibble: 3 x 4
      category       date   value1 value2
         <chr>     <date>    <dbl>  <dbl>
    1        A 2017-02-01 94.00000   56.0
    2        B 2017-04-01 96.50000   56.5
    3        C 2017-10-01 95.66667   55.0
    
    dt%>%
    组别(类别)%>%
    总结(日期=最大(日期),
    值1=平均值(值1),
    value2=平均值(value2))%>%
    解组()
    #一个tibble:3x4
    类别日期值1值2
    1A 2017-02-01 94.0000056.0
    2b 2017-04-01 96.50000 56.5
    3 C 2017-10-01 95.66667 55.0
    
    这就是你要找的吗

    dt %>%
      group_by(category) %>%
      summarise(date = max(date),
                value1 = mean(value1),
                value2 = mean(value2)) %>%
      ungroup()
    
    # A tibble: 3 x 4
      category       date   value1 value2
         <chr>     <date>    <dbl>  <dbl>
    1        A 2017-02-01 94.00000   56.0
    2        B 2017-04-01 96.50000   56.5
    3        C 2017-10-01 95.66667   55.0
    
    dt%>%
    组别(类别)%>%
    总结(日期=最大(日期),
    值1=平均值(值1),
    value2=平均值(value2))%>%
    解组()
    #一个tibble:3x4
    类别日期值1值2
    1A 2017-02-01 94.0000056.0
    2b 2017-04-01 96.50000 56.5
    3 C 2017-10-01 95.66667 55.0
    
    @Frank观点正确。我不知道
    dplyr
    sumerise\u all
    summary\u if
    ,或
    summary\u at
    in
    data.table
    @Frank感谢分享您的解决方案并报告错误
    if_else
    在这里是必需的,因为
    if else
    将强制日期列为数字。@Frank我注意到,如果我将您的代码从
    by=date
    更改为
    by=category
    ,这似乎会导致所需的输出,而不会出现警告或错误消息。如果您允许,我想将您的解决方案添加到我的帖子中作为补充。也可以使用
    max(date)
    ,它与
    last(date)
    dt%>%group\u by(category)%%>%summary\u all(funs)(如果其他(是数值(.),平均(.),last())相同
    是一种纯粹的R美。“我不同意我的拙见。”弗兰克说得很好。我不知道
    dplyr
    sumerise\u all
    summary\u if
    ,或
    summary\u at
    in
    data.table
    @Frank感谢分享您的解决方案并报告错误
    if_else
    在这里是必需的,因为
    if else
    将强制日期列为数字。@Frank我注意到,如果我将您的代码从
    by=date
    更改为
    by=category
    ,这似乎会导致所需的输出,而不会出现警告或错误消息。如果您允许,我想将您的解决方案添加到我的帖子中作为补充。也可以使用
    max(date)
    ,它与
    last(date)
    dt%>%group\u by(category)%%>%summary\u all(funs)(如果其他(是数值(.),平均(.),last())相同
    是一种纯粹的R美。我以我的拙见,很好的解决方案。我开发了一种类似的方法,使用
    summary_all
    ,以防OP中有很多列需要平均汇总。这是一个很好的解决方案。我开发了一种类似的方法,使用
    summary_all
    ,以防OP中有很多列需要平均汇总。