2014-12-04 10 views
7

는 I는 I이 속하는 2 개 질문했다 2
subset_df <- subset(df, age>5)R에서 데이터 프레임의 행을 부분 집합하는 더 빠른 방법?

방법을
방법 1
subset_df <- df[which(df$age>5) , ]
에게 R.에서 데이터 프레임의 데이터 부분 집합 상호 교환이 2 가지 방법을 사용하고있다.
1. 데이터가 매우 큰 것을 고려하면 어느 것이 더 빠릅니까?
2.이 게시물의 여기에 Subsetting data frames in R은 사실상 위의 두 가지 방법간에 차이가 있음을 나타냅니다. 그들 중 하나는 정확하게 NA를 처리합니다. 그럼 어느 것이 안전할까요?

+0

(1) 'microbenchmark'패키지로 일부 벤치 마크를 실행 해보십시오. – nrussell

+0

또한 https://stackoverflow.com/questions/9860090/in-r-why-is-better-than-subset –

+4

에서 확인하십시오. 큰 데이터 세트에서 속도가 걱정된다면 대신'dplyr' 또는'data.table' (또는'data.table'의 프론트 엔드로'dplyr')을 사용해야합니다. –

답변

15

이 질문은 데이터 프레임의 행을 부분 집합 화하는 더 빠른 방법을 묻습니다. 가장 빠른 방법은 data.table입니다. 이 간단한 경우 data.table에

set.seed(1) # for reproducible example 
# 1 million rows - big enough? 
df <- data.frame(age=sample(1:65,1e6,replace=TRUE),x=rnorm(1e6),y=rpois(1e6,25)) 

library(microbenchmark) 
microbenchmark(result<-df[which(df$age>5),], 
       result<-subset(df, age>5), 
       result<-df[df$age>5,], 
       times=10) 
# Unit: milliseconds 
#        expr  min  lq median  uq  max neval 
# result <- df[which(df$age > 5), ] 77.01055 80.62678 81.43786 133.7753 145.4756 10 
#  result <- subset(df, age > 5) 190.89829 193.04221 197.49973 203.7571 263.7738 10 
#   result <- df[df$age > 5, ] 169.85649 171.02084 176.47480 185.9394 191.2803 10 

library(data.table) 
DT <- as.data.table(df)  # data.table 
microbenchmark(DT[age > 5],times=10) 
# Unit: milliseconds 
#   expr  min  lq median  uq  max neval 
# DT[age > 5] 29.49726 29.93907 30.1813 30.67168 32.81204 10 

그래서 이상 6 배 빠른 subset(...)보다 두 배 빠른 which(...)으로보다 조금 더합니다.

+0

참고 : Windows에서이 버전을 R 3.3.1 64 비트에서 실행하면 처음 세 가지 옵션의 차이는 버전 작음 (평균 : 110-114, 중간 값 : 77-87)입니다. 어쩌면 R이 부분 집합을 처리하는 방식이 최적화 되었는가? 나는 data.table을 시도하지 않았다. 나는 아직도 더 빠르다고 생각한다. –

1

제가 첨가하여 코드 기록 재 :

  • 부분 집합 연산자 [;

  • 필터 "dplyr"패키지;

  • standard evaluation을 사용하는 함수.

    # 1. Libraries library(microbenchmark) library(data.table) library(dplyr) # 2. Reproducibility set.seed(1) # 3. Create data structures (1e6 rows) # 3.1. Data frame df <- data.frame( age = sample(1:65, 1e6, replace = TRUE), x = rnorm(1e6), y = rpois(1e6,25)) # 3.2. Data table dt <- as.data.table(df) # 4. Helper functions # 4.1. Function that uses standard evaluation # http://adv-r.had.co.nz/Computing-on-the-language.html subset2_q <- function(x, condition) { r <- eval(condition, x, parent.frame()) x[r, ] } subset2 <- function(x, condition) { subset2_q(x, substitute(condition)) } # 5. Benchmarks microbenchmark( # 5.1. Data frame (basic operations) df[which(df$age > 5), ], df[df$age > 5, ], subset(df, age > 5), df[df[['age']] > 5, ], # 5.2. Data frame (dplyr) df %>% filter(age > 5), # 5.3. Data table (basic) dt[age > 5], dt %>% filter(age > 5), # 5.4. Data frame and table with 'subset2' dt %>% subset2(age > 5), df %>% subset2(age > 5), # 5.5. How many times times = 10) # Results expr min lq mean median uq max neval cld df[which(df$age > 5), ] 83.07726 88.77624 102.20981 90.08606 91.52631 212.10305 10 b df[df$age > 5, ] 72.17319 79.98209 80.68900 81.42234 82.33832 84.46876 10 b subset(df, age > 5) 84.95796 85.90815 88.79125 88.03345 89.49680 95.37453 10 b df[df[["age"]] > 5, ] 71.39021 80.22755 81.86848 81.33061 82.38236 104.97732 10 b df %>% filter(age > 5) 21.37622 21.97020 23.57504 22.27681 25.17569 29.64354 10 a dt[age > 5] 20.26226 20.55946 36.58179 25.24155 29.68587 143.57794 10 a dt %>% filter(age > 5) 21.35613 21.76579 25.57424 22.02750 30.99570 32.18407 10 a dt %>% subset2(age > 5) 20.41449 20.57485 23.93314 20.70827 28.63391 31.15306 10 a df %>% subset2(age > 5) 77.43044 79.63956 92.24558 80.80100 81.61990 197.36958 10 b

가장 좋은 결과는 data.tableDF %> % 필터 (나이> 5) 사업자했다. 따라서 dplyr을 사용한 data.frame도 유용 할 수 있습니다.

관련 문제