2016-09-21 2 views
4

나는 목록에 data.frame 개체를 가지고 있으며, 각각 마지막 열 (A.K.A, score)을 기준으로 필터링을 수행 할 것입니다. 목록에 대한 부분 집합은 나에게 직관적이지만 각 data.frame 객체에 대해 필터링 결과로 두 가지 다른 집합 (예 : 통과/실패)을 원합니다. 나는 내가 사용하는 방식이 우아하지 않고 더 좋고/효율적인 해결책을 찾고 있다고 생각한다. 아무도 나 에게이 작업의 종류에 대한 더 우아한 솔루션을 달성하는 방법을 가리킬 수 있습니까? 고마워요!목록에서 큰 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) 

에서 mapdplyr에서 filter를 사용 각 list 요소를 사용하면 rbind 데이터 세트를 하나의 데이터 세트 (rbindlistdata.table 또는 bind_rows에서 dplyr 식별자 열로 변환) 및 그룹 별 하위 세트로 만들 수 있습니다.

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

또는 의도가 list 2에 data.frame를 분리하는 경우 dplyr

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

와 (> '점수'에 대한 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