By v1.9.2
, rbindlist
эволюционировал совсем немного, реализовав множество функций, в том числе:
- Выбор самого высокого
SEXPTYPE
столбца при привязке - реализовано при v1.9.2
закрытии FR # 2456 и Bug # 4981 .
factor
Правильная обработка столбцов - сначала реализована в v1.8.10
закрытии ошибки # 2650 и расширена для тщательного связывания упорядоченных факторов v1.9.2
, закрывая FR # 4856 и ошибку № 5019 .
Кроме того, в v1.9.2
, rbind.data.table
также появился fill
аргумент, позволяющий выполнять привязку путем заполнения недостающих столбцов, реализованный в R.
Теперь v1.9.3
есть еще больше улучшений в этих существующих функциях:
rbindlist
получает аргумент use.names
, который по умолчанию предназначен FALSE
для обратной совместимости.
rbindlist
также получает аргумент fill
, который по умолчанию также FALSE
для обратной совместимости.
- Все эти функции реализованы на C и написаны тщательно, чтобы не снижать скорость при добавлении функций.
- Поскольку
rbindlist
теперь можно сопоставлять по именам и заполнять пропущенные столбцы, rbind.data.table
просто звоните rbindlist
сейчас. Единственное отличие состоит в том, что use.names=TRUE
по умолчанию rbind.data.table
для обратной совместимости.
rbind.data.frame
немного замедляется, в основном из-за копий (что также указывает @mnel), которых можно было бы избежать (перейдя на C). Думаю, это не единственная причина. Реализация проверки / сопоставления имен столбцов rbind.data.frame
также может замедлиться, если на data.frame много столбцов и есть много таких data.frames для привязки (как показано в тесте ниже).
Однако rbindlist
отсутствие определенных функций (таких как проверка уровней факторов или сопоставление имен) имеет очень крошечный (или нулевой) вес для того, чтобы он работал быстрее, чем rbind.data.frame
. Это потому, что они были тщательно реализованы в C, оптимизированы для скорости и памяти.
Вот тест , который подчеркивает эффективное связывание, подбирая по именам столбцов , а также с помощью rbindlist
«s use.names
функции из v1.9.3
. Набор данных состоит из 10000 фреймов данных, каждый размером 10 * 500.
NB: этот тест был обновлен, чтобы включить сравнение dplyr
сbind_rows
library(data.table) # 1.11.5, 2018-06-02 00:09:06 UTC
library(dplyr) # 0.7.5.9000, 2018-06-12 01:41:40 UTC
set.seed(1L)
names = paste0("V", 1:500)
cols = 500L
foo <- function() {
data = as.data.frame(setDT(lapply(1:cols, function(x) sample(10))))
setnames(data, sample(names))
}
n = 10e3L
ll = vector("list", n)
for (i in 1:n) {
.Call("Csetlistelt", ll, i, foo())
}
system.time(ans1 <- rbindlist(ll))
# user system elapsed
# 1.226 0.070 1.296
system.time(ans2 <- rbindlist(ll, use.names=TRUE))
# user system elapsed
# 2.635 0.129 2.772
system.time(ans3 <- do.call("rbind", ll))
# user system elapsed
# 36.932 1.628 38.594
system.time(ans4 <- bind_rows(ll))
# user system elapsed
# 48.754 0.384 49.224
identical(ans2, setDT(ans3))
# [1] TRUE
identical(ans2, setDT(ans4))
# [1] TRUE
Связывание столбцов как таковых без проверки имен заняло всего 1,3, тогда как проверка имен столбцов и связывания соответственно заняла всего 1,5 секунды. По сравнению с базовым решением, это в 14 раз быстрее и в 18 раз быстрее, чем в dplyr
версии.
attr<-
,class<-
и (я думаю)rownames<-
все модифицируется на месте.