R中有两个相等的最大值

时间:2015-07-09 04:45:58

标签: r dataframe

我有一个包含一些数字(得分)和重复ID的数据框。我想获得每个ID的最大值。 我用过这个功能

top = aggregate(df$score, list(df$ID),max)

这为我返回了一个顶级数据框,其最大值对应于每个ID。

但实际上,对于其中一个ID,我们有两个EQUAL最大值。但是这个函数忽略了第二个值。

有没有办法保留最大值。?

例如:

DF

ID   score
1    12
1    15
1    1
1    15
2    23
2    12
2    13

以上功能给了我这个: 顶

ID    Score
1     15
2     23

我需要这个: 顶

ID   Score
1    15
1    15
2    23

5 个答案:

答案 0 :(得分:4)

您可以转换为data.table

DT <- as.data.table(df)
DT[, .SD[score == max(score)], by=ID]

答案 1 :(得分:4)

我建议克里斯提到data.table(对速度有利,但学习曲线更陡峭)。 或者,如果您不想data.table,则可以使用plyr

library(plyr)
ddply(df, .(ID), subset, score==max(score))
# same as ddply(df, .(ID), function (x) subset(x, score==max(score)))

答案 2 :(得分:3)

坚持data.frame

df[unlist(by(df, df$ID, FUN=function(D) rownames(D)[D$score == max(D$score)] )),]
#  ID score
#2  1    15
#4  1    15
#5  2    23

这是有效的,因为by会根据dfdf$ID拆分为data.frames列表,但保留rownames的原始df(见by(df, df$ID, I))。因此,返回每个组中与最大rownames值对应的每个D子集的score仍可用于对原始df进行子集化。

答案 3 :(得分:2)

这是一个dplyr解决方案。

library(dplyr)

df %>%
    group_by(ID) %>%
    filter(score == max(score))

否则,为了建立您已完成的工作,我们可以在您的“顶部”数据框架上使用merge的偷偷摸摸的属性,请参阅以下示例:

df1 <- data.frame(ID = c(1,1,5,2), score = c(5,5,2,6))

top_df <- data.frame(ID = c(1,2), score = c(5,6))

merge(df1, top_df)

给出:

  ID score
1  1     5
2  1     5
3  2     6

答案 4 :(得分:0)

一个简单的基础R解决方案:

df <- data.frame(ID = c(1, 1, 1, 1, 2, 2, 2), 
                 score = c(12, 15, 1, 15, 23, 12, 13))

有几个选择:

df[df$score %in% tapply(df$score, df$ID, max), ] 
df[df$score %in% aggregate(score ~ ID, data = df, max)$score, ]
df[df$score %in% aggregate(df$score, list(df$ID), max)$x, ] 

输出:

  ID score
2  1    15
4  1    15
5  2    23

使用sqldf

library(sqldf)
sqldf('SELECT df.ID, score FROM df 
  JOIN (SELECT ID, MAX(score) AS score FROM df GROUP BY ID)
  USING (score)')

输出:

  ID score
2  1    15
4  1    15
5  2    23