2016-09-21 14 views
4

我在列表中有data.frame對象,我將根據每個列的最後一列(A.K.A,score)分別過濾掉。子集列表對我來說很直觀,但是我希望有兩個不同的集合(即通過/失敗)作爲每個data.frame對象的過濾結果。我認爲我使用的方式並不高雅,並尋求更好/有效的解決方案。任何人都可以指出我如何爲這類任務實現更優雅的解決方案?非常感謝 !如何有效地爲列表中的大數據框架對象子集?

玩具數據:

mylist <- list(df1=data.frame(from=seq(1, by=4, len=16), to=seq(3, by=4, len=16), score=sample(30, 16)), 
       df2=data.frame(from=seq(3, by=7, len=20), to=seq(6, by=7, len=20), score=sample(30, 20)), 
       df3=data.frame(from=seq(4, by=8, len=25), to=seq(7, by=8, len=25), score=sample(30, 25))) 

我初步的嘗試:

pass <- lapply(mylist, function(ele_) { 
    ans <- subset(ele_, ele_$score > 20) 
    ans 
}) 

原來我想也有其相對的一組其中爲實例不符合過濾條件,並把及格,不及格爲每個data.frame對象設置一個列表。

期望的輸出:每個data.frame對象可以在子集化之後通過,失敗設置。

如果我在列表中有非常大的data.frame對象,這樣做會更好嗎?有沒有人知道這個有用的技巧?

回答

6

可能是data.table選擇將是更有效的

library(data.table) 
lapply(mylist, function(x) setDT(x)[score > 20]) 

或者從purrr

library(dplyr) 
library(purrr) 
mylist %>% 
     map(filter, score > 20) 

使用filterdplyrmap除了子集上述方法每個list元素,我們也可以將rbind數據集合成單個數據集(來自data.tablerbindlist或具有標識符列的dplyrbind_rows)並且按組逐個子集。

rbindlist(mylist, idcol= 'grp')[score > 20, .SD , by = .(grp)] 

或用dplyr

mylist %>% 
    bind_rows(., .id = 'grp') %>% 
    group_by(grp) %>% 
    filter(score > 20) 

如果目的是將data.frame分離成2的list(> 20和< 20 '得分')

lapply(mylist, function(x) split(x, c("FAIL", "PASS")[(x$score > 20)+1])) 
+0

@ Andy.Jian我不確定我是否正確理解你的評論。據我所知,這個問題是關於用更高效的代碼替換你的代碼。 – akrun

+0

你的代碼肯定是有效的。我編輯了我的評論 –

+0

@ Andy.Jian更新了'split'的帖子 – akrun

相關問題