我有一个数据框full
我想从中取出最后一列和一列v
。然后我想对两列进行排序v
以尽可能最快的方式。full
从 csv 中读取,但这可以用于测试(包括一些真实性的 NA):
n <- 200000
full <- data.frame(A = runif(n, 1, 10000), B = floor(runif(n, 0, 1.9)))
full[sample(n, 10000), 'A'] <- NA
v <- 1
I have v
作为这里的一员,但实际上它可能会改变,并且full
有很多列。
我尝试过对数据框、数据表和矩阵进行排序order
and sort.list
(一些想法取自这个线程 https://stackoverflow.com/questions/1296646/how-to-sort-a-dataframe-by-columns-in-r)。所有这些的代码:
# DATA FRAME
ord_df <- function() {
a <- full[c(v, length(full))]
a[with(a, order(a[1])), ]
}
sl_df <- function() {
a <- full[c(v, length(full))]
a[sort.list(a[[1]]), ]
}
# DATA TABLE
require(data.table)
ord_dt <- function() {
a <- as.data.table(full[c(v, length(full))])
colnames(a)[1] <- 'values'
a[order(values)]
}
sl_dt <- function() {
a <- as.data.table(full[c(v, length(full))])
colnames(a)[1] <- 'values'
a[sort.list(values)]
}
# MATRIX
ord_mat <- function() {
a <- as.matrix(full[c(v, length(full))])
a[order(a[, 1]), ]
}
sl_mat <- function() {
a <- as.matrix(full[c(v, length(full))])
a[sort.list(a[, 1]), ]
}
时间结果:
ord_df sl_df ord_dt sl_dt ord_mat sl_mat
Min. 0.230 0.1500 0.1300 0.120 0.140 0.1400
Median 0.250 0.1600 0.1400 0.140 0.140 0.1400
Mean 0.244 0.1610 0.1430 0.136 0.142 0.1450
Max. 0.250 0.1700 0.1600 0.140 0.160 0.1600
或者使用microbenchmark
(结果以毫秒为单位):
min lq median uq max
1 ord_df() 243.0647 248.2768 254.0544 265.2589 352.3984
2 ord_dt() 133.8159 140.0111 143.8202 148.4957 181.2647
3 ord_mat() 140.5198 146.8131 149.9876 154.6649 191.6897
4 sl_df() 152.6985 161.5591 166.5147 171.2891 194.7155
5 sl_dt() 132.1414 139.7655 144.1281 149.6844 188.8592
6 sl_mat() 139.2420 146.8578 151.6760 156.6174 186.5416
看起来好像排序数据表获胜。两者之间并没有太大区别order
and sort.list
除非使用数据框时sort.list
速度要快得多。
在数据表版本中我也尝试设置v
作为键(因为它然后根据文档进行排序),但我无法让它工作,因为内容v
都不是整数。
理想情况下,我希望尽可能加快速度,因为我必须针对不同的情况多次执行此操作v
价值观。有谁知道我如何能够进一步加快这个过程?也可能值得尝试Rcpp
执行?谢谢。
这是我用于计时的代码(如果对任何人有用的话):
sortMethods <- list(ord_df, sl_df, ord_dt, sl_dt, ord_mat, sl_mat)
require(plyr)
timings <- raply(10, sapply(sortMethods, function(x) system.time(x())[[3]]))
colnames(timings) <- c('ord_df', 'sl_df', 'ord_dt', 'sl_dt', 'ord_mat', 'sl_mat')
apply(timings, 2, summary)
require(microbenchmark)
mb <- microbenchmark(ord_df(), sl_df(), ord_dt(), sl_dt(), ord_mat(), sl_mat())
plot(mb)