Производительность назначения в конструкторе data.frame
У меня проблемы с пониманием того, как data.frame
строительные работы.
Я видел этот вопрос, но я думал, что предварительное назначение столбцов в 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
1 ответ
Изменения n=100000
и работает ваш microbenchmark()
для 1000 испытаний, чтобы сгладить любой вариант, получается следующее:
> microbenchmark(f_dollar(), f_named(), f_unnamed(), times=1000)
Unit: microseconds
expr min lq mean median uq max neval
f_dollar() 16559.490 17000.361 17444.4909 17282.3785 17587.723 24130.81 1000
f_named() 211.338 233.266 277.4680 254.2595 302.779 2028.94 1000
f_unnamed() 260.325 288.783 391.2701 313.7420 366.693 44304.51 1000
Это поддержало бы ваше первоначальное впечатление, что создание вашего объекта data.frame с включенными данными гораздо более эффективно, чем добавление его после факта, который воссоздает data.frame в каждой переменной, насколько я знаю.