按组别汇总,并列出每个组别的最新记录

3

I have a dataframe:

df <- data.frame(Xdate = c("21-jul-2020", "29-jul-2020", "20-jul-2020", "13-may-2020" ),
                 names = c("peter", "lisa","peter", "lisa"),
                 score = c(1,3,5,7))

如何优雅地获取最新的分数:

df_result <- data.frame(names = c("peter", "lisa"),
                        score = c(1, 3))

Peter最新的得分是1,这一成绩是在2020年7月21日获得的。Lisa最新的得分是3,是在2020年7月29日获得的。


我不确定我理解为什么你需要聚合,如果你只想读出最后得分。你能详细说明一下吗? - D.J
4个回答

5

dplyr 中,您可以使用 slice_max() 来选择最新日期,该函数在版本 1.0.0 之后取代了 top_n()

library(dplyr)

df %>%
  mutate(Xdate = as.Date(Xdate, "%d-%b-%Y")) %>%
  group_by(names) %>%
  slice_max(Xdate, n = 1) %>%
  ungroup()

# # A tibble: 2 x 3
#   Xdate      names score
#   <date>     <chr> <dbl>
# 1 2020-07-29 lisa      3
# 2 2020-07-21 peter     1

3

以下是dplyr解决方案。

library(dplyr)

df %>%
  mutate(Xdate = as.Date(df$Xdate, "%d-%b-%Y")) %>%
  group_by(names) %>%
  arrange(Xdate) %>%
  summarise_all(last)
## A tibble: 2 x 3
#  names Xdate      score
#  <chr> <date>     <dbl>
#1 lisa  2020-07-29     3
#2 peter 2020-07-21     1

一个基于R语言的一行代码可能是:

aggregate(score ~ names, data = df[order(df$Xdate),], function(x) x[length(x)])
#  names score
#1  lisa     3
#2 peter     1

2

这里有一个来自dplyr包的替代方案

library(dplyr)
    df$Xdate <- as.Date(df$Xdate, format = "%d-%b-%Y")
    df %>% 
        group_by(names) %>% 
        arrange(desc(Xdate)) %>% 
        mutate(names = first(names),
               score = first(score)) %>% 
        select(!Xdate) %>% 
        distinct(names, score)%>%
        ungroup()

# names score
# <fct> <dbl>
#1 lisa      3
#2 peter     1

或者

df %>% group_by(names) %>% arrange(desc(Xdate)) %>% filter(row_number() == 1)

或者

df %>% group_by(names) %>% arrange(desc(Xdate)) %>% top_n(n = -1)

谢谢。我也想到了类似的东西,但是没有“一行代码”的方法来完成这个任务吗? - Soren Christensen
@SorenStillingChristensen 你也可以尝试这个。 - Sri Sreshtan

2

在基本R中使用ave

subset(transform(df, Xdate = as.Date(Xdate, "%d-%b-%Y")), 
                     Xdate == ave(Xdate, names, FUN = max))

#       Xdate names score
#1 2020-07-21 peter     1
#2 2020-07-29  lisa     3

使用transform,我们首先将Xdate转换为日期格式,使用ave获取每个names的最大日期并且对这些值进行subset


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接