我一直在使用这两种方法交替地从R数据框中对数据进行子集筛选。
方法1
subset_df <- df[which(df$age>5) , ]
方法2
subset_df <- subset(df, age>5)
我有两个问题关于这些。
1. 如果我有非常大的数据,哪一个更快?
2. 这篇文章Subsetting data frames in R表明上述两种方法之间实际上是有差异的。其中一种可以准确地处理NA(缺失值)。那么哪种方法更安全可靠呢?
我一直在使用这两种方法交替地从R数据框中对数据进行子集筛选。
方法1
subset_df <- df[which(df$age>5) , ]
方法2
subset_df <- subset(df, age>5)
我有两个问题关于这些。
1. 如果我有非常大的数据,哪一个更快?
2. 这篇文章Subsetting data frames in R表明上述两种方法之间实际上是有差异的。其中一种可以准确地处理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(...)
快六倍以上。
我通过以下方式重写了代码:
使用子集运算符[[;
使用"dplyr"包中的filter函数;
编写了一个利用标准评估的函数。
最佳结果是使用 data.table 和 df %>% filter(age > 5) 运算符。因此,带有 dplyr 的 data.frame 也可能有用。
microbenchmark
包运行一些基准测试。 - nrusselldplyr
或data.table
(或者将dplyr
作为data.table
的前端)来代替。 - Ben Bolker[
是编程中的安全选择,而subset
仅适用于交互式使用的便利函数。有关更多信息,请参见上面的链接。 - talat