我有一个包含一些数字(得分)和重复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
答案 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
会根据df
将df$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