У меня возникли проблемы с пониманием того, как data.frame
строительные работы.Выполнение задания в конструкторе data.frame
Я видел this question, но я думал, что предварительное назначение столбцов в data.frame
было медленным, если вы захотели заменить данные после этого (дублированная работа).
Затем я выполнил следующий тест и обнаружил, что передача данных в качестве аргументов в конструктор data.frame
намного медленнее, чем просто создание data.frame
, а затем назначение данных.
Что здесь происходит?
library(microbenchmark)
# Prep -------------------#
n = 1000
s = seq(n)
f = runif(n)
g = as.factor(sample(1:100, size = n, replace = T))
h = runif(n)
i = sample(LETTERS[1:26], size = n, replace = T)
# Functions --------------#
## Construct data.frame and then assign
f_dollar = function(){
d = data.frame(row.names = s,
check.rows = F, check.names = F, stringsAsFactors = F)
d$first = f
d$second = g
d$third = h
d$fourth = i
}
## Construct data.frame assigning named vectors
f_named = function(){
d = data.frame(first = f, second = g, third = h, fourth = i,
check.rows = F, check.names = F, stringsAsFactors = F)
}
## Construct data.frame assigning unnamed vectors
f_unnamed = function(){
d = data.frame(f, g, h, i,
check.rows = F, check.names = F, stringsAsFactors = F)
}
# Profile ----------------#
microbenchmark(f_dollar(), f_named(), f_unnamed())
И результаты:
Unit: microseconds
expr min lq mean median uq max neval
f_dollar() 65.808 79.691 92.5668 87.3850 100.6715 191.446 100
f_named() 205.962 221.761 245.2758 231.8325 251.2915 538.911 100
f_unnamed() 269.416 283.689 339.8429 297.1045 332.8925 2800.185 100
Согласен, ваши результаты вначале не интуитивно понятны, но могут быть побочным продуктом использования таких небольших наборов данных. Если вы набросаете свой n до 100000, вы должны увидеть результаты, соответствующие вашим ожиданиям (по крайней мере, я). –
Если вы посмотрите на код для 'data.frame', вы можете заметить, что в случае отсутствия данных (как в' f_dollar') он выходит очень рано. Мое предположение заключалось бы в том, что '$ <-' имеет меньше накладных расходов, чем взбалтывание остальной части кода в 'data.frame', по крайней мере, для масштаба данных в этом примере. – joran