我一直在使用這2種方法中可互換到子集從數據幀的數據在R.
方法1
subset_df <- df[which(df$age>5) , ]
方法2
subset_df <- subset(df, age>5)
在R中的數據框的行上子集的更快方法?
我不得不屬於這些2個問題。
1.考慮到我有非常大的數據,哪一個更快?
2.這篇文章Subsetting data frames in R表明上述2種方法實際上有區別。其中一人能夠準確處理NA。哪一個可以安全使用呢?
我一直在使用這2種方法中可互換到子集從數據幀的數據在R.
方法1
subset_df <- df[which(df$age>5) , ]
方法2
subset_df <- subset(df, age>5)
在R中的數據框的行上子集的更快方法?
我不得不屬於這些2個問題。
1.考慮到我有非常大的數據,哪一個更快?
2.這篇文章Subsetting data frames in R表明上述2種方法實際上有區別。其中一人能夠準確處理NA。哪一個可以安全使用呢?
該問題要求更快的方式來對數據框的子集進行子集劃分。最快的方法是使用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
所以在這個簡單的例子data.table比快兩倍which(...)
多一點,比subset(...)
快6倍以上。
注意:在Windows上的R 3.3.1 64位上運行此版本,前三個選項之間的差別是版本較小(平均值:110 - 114,中值:77-87)。也許R處理子集的方式已經優化了?我還沒有嘗試data.table,我認爲它仍然更快。 – 2016-08-24 14:50:25
我通過加入重新寫入代碼:
子集操作者[[;
filter from「dplyr」package;
功能使用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.table和DF%>%濾波器(年齡> 5)運算符。因此,使用dplyr的data.frame也可能很有用。
對於(1)嘗試運行一些基準測試包'microbenchmark' – nrussell 2014-12-04 21:44:40
另請參見https://stackoverflow.com/questions/9860090/in-r-why-is-better-than-subset – 2014-12-04 21:49:31
如果您'再次擔心大數據集的速度,您應該使用'dplyr'或'data.table'(或'dplyr'作爲data.table'的前端)。 – 2014-12-04 21:49:31