【问题标题】:How to make a unique in R by column A and keep the row with maximum value in column B如何在 A 列中创建唯一的 R 并在 B 列中保留最大值的行
【发布时间】:2013-01-15 10:30:03
【问题描述】:

我有一个包含几列 (17) 的 data.frame。 第 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 建议,但它们需要永远。任何想法最有效?

【问题讨论】:

  • 搜索tapplyplyr,你会发现很多很多相同的问题。
  • 关于更新:您需要提供更多信息。我已经测试了 10M 行和 26 组的 data.table 解决方案,性能令人满意。
  • 我正在测试提供的第一个解决方案。 Roland 的最后一次更新需要几分钟时间。谢谢!

标签: r unique


【解决方案1】:

使用包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) 和 by = 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
【解决方案2】:

使用 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 究竟想要实现什么。
  • 此解决方案为每列选择最大值,但 OP 要求选择 完整行,其中第 17 列具有最高值。 @Roland 的答案是目前唯一正确的答案。