【问题标题】:select rows with largest value of variable within a group in r在 r 中的组中选择具有最大变量值的行
【发布时间】:2011-02-18 19:30:03
【问题描述】:
a.2<-sample(1:10,100,replace=T)
b.2<-sample(1:100,100,replace=T)
a.3<-data.frame(a.2,b.2)

r<-sapply(split(a.3,a.2),function(x) which.max(x$b.2))

a.3[r,]

返回列表索引,而不是整个 data.frame 的索引

我试图为a.2 的每个子组返回b.2 的最大值。我怎样才能有效地做到这一点?

【问题讨论】:

  • 融化(a.3,id=c("a.2"))->h.2; cast(h.2,a.2~,max) 在这个例子中起到了作用,但是当我将它应用于我的原始数据集时,计算机内存不足。所以对我帮助不大。

标签: r groupwise-maximum


【解决方案1】:
a.2<-sample(1:10,100,replace=T)
b.2<-sample(1:100,100,replace=T)
a.3<-data.frame(a.2,b.2)
m<-split(a.3,a.2)
u<-function(x){
    a<-rownames(x)
    b<-which.max(x[,2])
    as.numeric(a[b])
    }
r<-sapply(m,FUN=function(x) u(x))

a.3[r,]

这可以解决问题,尽管有点麻烦......但它允许我抓取分组最大值的行。还有其他想法吗?

【讨论】:

    【解决方案2】:
    > a.2<-sample(1:10,100,replace=T)
    > b.2<-sample(1:100,100,replace=T)
    > tapply(b.2, a.2, max)
     1  2  3  4  5  6  7  8  9 10 
    99 92 96 97 98 99 94 98 98 96 
    

    【讨论】:

      【解决方案3】:
      a.2<-sample(1:10,100,replace=T)
      b.2<-sample(1:100,100,replace=T)
      a.3<-data.frame(a.2,b.2)
      

      Jonathan Chang 的答案可以得到您明确要求的内容,但我猜您想要数据框中的实际行。

      sel <- ave(b.2, a.2, FUN = max) == b.2
      a.3[sel,]
      

      【讨论】:

      • 我必须承认这要简单得多。但是 == b.2 背后的逻辑超出了我的理解...
      • ave 为每个 a.2 生成一个只包含 b.2 最大值的向量。因此,只要数据框有行,it == b.2 就设置一个真值。您正在使用逻辑向量来选择数据框中的行。如果您想查看它是如何工作的,请将 ave 命令的结果添加到您的数据框中并查看它,与 b.2 列进行比较 -- a.3$b.max
      【解决方案4】:
      library(plyr)
      ddply(a.3, "a.2", subset, b.2 == max(b.2))
      

      【讨论】:

      • 我尝试使用 ddply 函数,但速度非常慢。我没有计时,但它持续了一杯咖啡和一次去洗手间,而 ave 版本在我的原始数据集中仅使用了 0.2 秒(210col*16000rows)。
      • 这将在下一个版本中修复。但是,除非您提供一个现实的例子,否则您不能期望得到适用于您的数据的答案!
      【解决方案5】:

      我认为ddplyave 方法都相当耗费资源。 ave 因我当前的问题(67,608 行,四列定义唯一键)内存不足而失败。 tapply 是一个方便的选择,但我通常需要做的是为每个唯一键(通常由多于一列定义)选择所有具有某些值的整行。我发现的最佳解决方案是进行排序,然后使用duplicated 的否定来仅选择每个唯一键的第一行。对于这里的简单示例:

      a <- sample(1:10,100,replace=T)
      b <- sample(1:100,100,replace=T)
      f <- data.frame(a, b)
      
      sorted <- f[order(f$a, -f$b),]
      highs <- sorted[!duplicated(sorted$a),]
      

      我认为至少,与aveddply 相比,性能提升是可观的。多列键稍微复杂一些,但order 会处理一大堆要排序的事情,而duplicated 可以处理数据帧,因此可以继续使用这种方法。

      【讨论】:

      • 这是最容易使用的,并且在多列上效果很好——您需要做的就是在duplicated 中使用cbind
      【解决方案6】:
      a.2<-sample(1:10,100,replace=T)
      b.2<-sample(1:100,100,replace=T)
      a.3<-data.frame(a.2,b.2)
      

      使用aggregate,您可以在一行中获得每个组的最大值:

      aggregate(a.3, by = list(a.3$a.2), FUN = max)
      

      这会产生以下输出:

         Group.1 a.2 b.2
      1        1   1  96
      2        2   2  82
      ...
      8        8   8  85
      9        9   9  93
      10      10  10  97
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-17
        • 1970-01-01
        • 2021-07-23
        • 2020-08-04
        • 2021-07-23
        • 2021-01-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多