【问题标题】:Selecting the first nth rows by group with number of rows varied按组选择前 n 行,行数不同
【发布时间】:2011-03-07 17:45:01
【问题描述】:

我喜欢选择数据框中每个组的前 (2,3,0,4) 行。

> f<-data.frame(group=c(1,1,1,2,2,3,4),y=c(1:7))
> 
>   group y
>      1 1
>      1 2
>      1 3
>      2 4
>      2 5
>      3 6
>      4 7

并获取如下数据框

group y
1 1
1 2
2 4
2 5
4 7

我尝试使用 byhead,但 head 没有使用向量。

感谢您的帮助。

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    用更传统的lapply

    k <- c(2,3,0,4)
    fs <- split(f, f$group)
    do.call(rbind,lapply(seq_along(k), function(i) head(fs[[i]], k[i])))
    

    结果是:

      group y
    1     1 1
    2     1 2
    4     2 4
    5     2 5
    7     4 7
    

    【讨论】:

    • 我几乎提交了几乎相同的代码......再次。我们认为非常类似。
    • @Joshua:谢谢你的夸奖。我很感谢您在这里提供的许多有用的答案。顺便说一句,我今天早些时候看到我比你快,只是因为你先编辑了问题——感谢你花时间把问题也做得更好。
    • 巧妙的做法。我在组中有一个大约 50K 类别的大型数据框。知道这有多快。干杯
    • @Tony:很难说;我相信split 将创建一个新的数据对象,如果这是真的并且f 非常大,那可能需要一段时间。如果它被证明太慢,Hadley 的plyr 包应该会更快地完成一些类似的事情,你可以尝试一下(就像在 Sacha 的解决方案中一样)。如果您只想要每组中的几行,那么精心编写的 for 循环也完全有可能对此进行改进。另一种可能性是简化split,因为只需要保留y,但这会使簿记复杂化。
    【解决方案2】:

    使用plyr

    library(plyr)
    rows <- c(2,3,0,4)
    ddply(f,.(group),function(x)head(x,rows[x[1,1]]))
            group y
        1     1 1
        2     1 2
        3     2 4
        4     2 5
        5     4 7
    

    编辑:

    误解了问题所以更新了答案

    【讨论】:

      【解决方案3】:

      带索引的函数版本。

      fun1 <- function(){
        idx <- c(0,which(diff(f$group)!=0))+1
        idx2 <- unlist(lapply(1:length(nf),function(x)  seq.int(from=idx[x],length.out=nf[x])),use.names=F)
        f1 <- f[idx2,]
        return(f1)
      }
      
      fun2 <- function(){
        ddply(f,.(group),function(x) head(x,nf[x[1,1]]))
      }
      

      测试数据(问题作者建议的大小)

      f<-data.frame(group=sample(1:1000,50000,T),y=c(1:50000))
      f <- f[order(f$group),]
      nf <- rpois(length(unique(f$group)),3) 
      

      system.time(fun1()) system.time(fun2())

      在我的系统上快 60 倍很有趣1。

      【讨论】:

      • 我用我的数据集测试你的代码,它确实非常快。对于 ddply,我收到以下错误消息 Error in if (n &lt; 0L) max(nrow(x) + n, 0L) else min(n, nrow(x)) : missing value where TRUE/FALSE needed
      • 您的组变量中可能缺少值。您可以将缺失值重新编码为某个值或使用 na.omit(f)。
      猜你喜欢
      • 2013-10-10
      • 1970-01-01
      • 2021-11-12
      • 2013-01-25
      • 2021-07-09
      • 2021-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多