Самая быстрая сортировка по столбцам в R

У меня есть кадр данных 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)

15
задан Community 23 May 2017 в 12:08
поделиться