如何在R中通过A列创建唯一值,并保留B列最大值所在的行。

4

我有一个包含17列的数据框。 第2列有多行具有相同的值,我想保留其中的一行,具体来说是在第17列中具有最大值的那一行。

例如:

A    B
'a'  1
'a'  2
'a'  3
'b'  5
'b'  200

Would return
A    B
'a'  3
'b'  200

(加上其他列)

到目前为止,我一直在使用unique函数,但我认为它随机保留一个或仅保留第一个出现的。

**更新** 真实数据有376000行。我尝试了data.table和ddply建议,但它们需要很长时间。有没有什么方法最有效?


2
搜索tapplyplyr,你会发现很多很多完全相同的问题。 - Andrie
关于更新:您需要提供更多信息。我已经测试了数据表解决方案,使用了1000万行和26个组,性能令人满意。 - Roland
我正在测试提供的第一个解决方案。Roland 的最后一次更新需要几分钟时间。谢谢! - biojl
2个回答

6

使用data.table包的解决方案:

set.seed(42)
dat <- data.frame(A=c('a','a','a','b','b'),B=c(1,2,3,5,200),C=rnorm(5))
library(data.table)

dat <- as.data.table(dat)
dat[,.SD[which.max(B)],by=A]

   A   B         C
1: a   3 0.3631284
2: b 200 0.4042683

但是对于多列,结果会有NAs(数据仅包含数字)。我想要得到max(col1,col2,col3),并且按照col3,col4,col5进行分组?我尝试将其扩展为dat[,.SD[which.max(col1,col2,col3), by=c(col3,col4,col5)]。但结果看起来不对。寻找select col3,col4,col5,max(col1) as col1,max(col2) as col2,max(col3) as col3 group by col3,col4,col5 - sjd

3

使用R基本函数的解决方案并不太优雅

> ind <- with(dat, tapply(B, A, which.max)) # Using @Roland's data
> mysplit <- split(dat, dat$A)
> do.call(rbind, lapply(1:length(mysplit), function(i) mysplit[[i]][ind[i],]))
  A   B         C
3 a   3 0.3631284
5 b 200 0.4042683

这与我的答案有所不同,而且不清楚OP想要实现什么。 - Roland
3
这个解决方案选择每列的最大值,但是OP要求选择一个完整的行,其中第17列具有最高的值。Roland的答案现在是唯一正确的。 - betabandido

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