Производительность назначения в конструкторе 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 в каждой переменной, насколько я знаю.

Другие вопросы по тегам