8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

通过选择每组一行来折叠数据框

chaos 2月前

102 0

我试图通过从特定列中具有相同值的每组行中删除一行以外的所有行来折叠数据框。换句话说,就是每组的第一行。例如,我...

我试图通过从特定列中具有相同值的每组行中删除一行以外的所有行来折叠数据框。换句话说,就是每组的第一行。

例如,我想转换这个

> d = data.frame(x=c(1,1,2,4),y=c(10,11,12,13),z=c(20,19,18,17))
> d
  x  y  z
1 1 10 20
2 1 11 19
3 2 12 18
4 4 13 17

变成这样:

    x  y  z
1   1 11 19
2   2 12 18
3   4 13 17

我目前正在使用聚合来执行此操作,但是当数据较多时,性能是不可接受的:

> d.ordered = d[order(-d$y),]
> aggregate(d.ordered,by=list(key=d.ordered$x),FUN=function(x){x[1]})

我已尝试使用与此处相同的函数参数进行 split/unsplit,但 unsplit 会抱怨行号重复。

rle 有可能吗?是否有一个 R 习语可以将 rle 的长度向量转换为每次运行开始的行的索引,然后我可以使用该习语从数据框中抽出这些行?

帖子版权声明 1、本帖标题:通过选择每组一行来折叠数据框
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由chaos在本站《loops》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 也许 duplicated() 能有所帮助:

    R> d[ !duplicated(d$x), ]
      x  y  z
    1 1 10 20
    3 2 12 18
    4 4 13 17
    R> 
    

    编辑 哎呀,没关系。这会在每个重复块中选择第一个,而您想要的是最后一个。因此,这是使用 plyr :

    R> ddply(d, "x", function(z) tail(z,1))
      x  y  z
    1 1 11 19
    2 2 12 18
    3 4 13 17
    R> 
    

    在这里, plyr 使用 z 以下方法返回块中的最后一组观察结果: tail(z, 1) .

  • 因此,您只需添加一个“处理步骤”即可创建一个 plyr 可以循环的因子变量。这一切都可以通过索引命令完成,试试看。顺便说一句,您的文本(表示选择了第一行)和示例(显示第二行)不一致。

  • 顺便说一句,在 r-help 和这里之间交叉发布也有点不合时宜。你在 r-help 上得到了很好的答案,那么你为什么不研究一下呢?

  • 我很荣幸。作为 StackOverflow 上的常见最佳实践,您应该接受一个帖子作为解决方案(如果您认为它提供了一个解决方案),并通过单击向上箭头对每个有用的帖子进行投票。这就是这里的评分方式。

  • 只需对 Dirk 提供的内容进行一点补充... duplicated 有一个 fromLast 可用于选择最后一行的参数:

    d[ !duplicated(d$x,fromLast=TRUE), ]
    
  • 嗨,Ian——不幸的是,James 从来没有真正明确地说明他想要的是第一个还是最后一个,并且在帖子中自相矛盾……但是你关于 fromLast 的提示很好!

  • 谢谢,这招很管用。我需要的是第一个还是最后一个,这完全取决于排序,而使用 fromLast,我可以以任何一种方式处理它

  • 这是一个 data.table 对于大型数据集来说可以节省时间和内存的解决方案

    library(data.table)
    DT <- as.data.table(d)           # convert to data.table
    setkey(DT, x)                    # set key to allow binary search using `J()`
    DT[J(unique(x)), mult ='last']   # subset out the last row for each x
    DT[J(unique(x)), mult ='first']  # if you wanted the first row for each x
    
  • 引用 10

    但是如果所需要的只是每个组中的最后一行,那么 DT[!duplicated(x,fromLast=TRUE)] 可能比 setkey + join 的总时间更快,并且具有一些语法优势,可以避免 DT 的变量名重复(即仅 x 而不是 DT$x)。

  • 我猜使用行索引会加快速度,DT[DT[,.I[.N],by = x]$V1]。检查 .com/questions/19424762/…。感谢@Simono101

  • unique(DT,by=\'x\',fromLast=TRUE) 现在比 DT[!duplicated(x,fromLast=TRUE)] 和 DT[J(unique(x)), mult ='last'] 更简单、更快

  • 有以下几种使用方式 dplyr

    library(dplyr)
    df %>% distinct(x, .keep_all = TRUE)
    df %>% group_by(x) %>% filter(row_number() == 1)
    df %>% group_by(x) %>% slice(1)
    

    您可以使用多个同时具有 和 的 distinct() group_by()

    df %>% distinct(x, y, .keep_all = TRUE)
    

    如果存在日期或其他顺序字段,并且您想确保保留最新的观察结果,则 group_by() and filter() ,如果您想避免平局,则 slice()

    df %>% group_by(x) %>% filter(date == max(date)) %>% slice(1)
    
  • dplyr::top_n() 也是一个选项,请参阅.com/questions/13279582/…

返回
作者最近主题: