2010-04-13 40 views
16

我試圖通過從特定列中具有相同值的每行組中刪除除一行以外的所有行來摺疊數據框。換句話說,每組的第一行。通過選擇每組一行來摺疊數據框

例如,我想這

> 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抱怨abo請重複行號。

是否有可能?是否有一個R語言將rle的長度向量轉換爲開始每次運行的行的索引,然後我可以使用這些索引將這些行從數據框中提取出來?

回答

25

也許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確實找到獨特的子集,遍歷它們並應用提供的功能的辛勤工作 - 它簡單的返回最後一組觀測使用tail(z, 1)z

+0

我寧願所有列,感謝 – jkebinger 2010-04-13 02:20:11

+0

,那麼你需要簡單地添加一個「處理步驟」打造一個因子變量在其plyr可以循環。它可以用索引命令完成,試試看。順便說一下,你的文本(選擇第一行)和示例(顯示第二行)之間不一致。 – 2010-04-13 02:51:49

+0

順便說一下,r-help和這裏之間的交叉發帖也有些差勁。你在r-help上得到了很好的答案,那你爲什麼不研究它們? – 2010-04-13 02:59:15

12

只是爲了一點點添加到什麼德克提供... duplicatedfromLast說法,你可以用它來選擇最後一行:

d[ !duplicated(d$x,fromLast=TRUE), ] 
+1

嗨伊恩 - 不幸的是,詹姆斯從來沒有真正明確過他是否想要第一個或最後一個,並且在帖子中自相矛盾......但是從最後一個角度來看,這是一個好主意! – 2010-04-13 12:14:43

+0

謝謝,這就像一個魅力。無論是第一次還是最後一次我需要的都是真正的排序,並且從最後我可以以任何方式攻擊 – jkebinger 2010-04-13 12:54:32

+0

我建議了同樣的事情,並且以「更喜歡所有列」爲理由而將它擊落。這怎麼不再重要? – 2010-04-13 13:35:24

10

這裏是一個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 
+0

如何重複工作但如果所需的_all_是每個組中的最後一行,那麼'DT [!duplicated(x,fromLast = TRUE)]'可能比總時間''setkey' + join,並且避免了'DT'的變量名稱重複(即只是'x'而不是'DT $ x')的一些語法糖優勢。 – 2012-09-19 08:43:02

+0

使用行索引會加快我的速度,DT [DT [,.I [.N],by = x] $ V1]。檢查http://stackoverflow.com/questions/19424762/efficiently-selecting-top-number-of-rows-for-each-unique-value-of-a-column-in-a。感謝@ Simono101 – Freddy 2013-11-20 10:36:27

+2

'唯一的(DT,by =「x」,fromLast = TRUE)'現在比'DT [!duplicated(x,fromLast = TRUE)]'和DT [J(unique(x )),mult ='last']' – Matthew 2014-09-02 01:50:03