У меня есть кадр данных 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
У меня есть v
как один здесь, но на самом деле он может измениться, и full
имеет много столбцов.
Я пробовал сортировать кадры данных, таблицы данных и матрицы с order
и sort.list
(. некоторые идеи взяты из этой ветки). Код для всех этих:
# 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
и 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)