web-dev-qa-db-fra.com

Comment initialiser un bloc de données vide (beaucoup de colonnes en même temps) dans R

J'ai trouvé comment initialiser un bloc de données vide à 3 ou 4 dimensions. C'est comme

df <- data.frame(Date=as.Date(character()),
             File=character(), 
             User=numeric(), 
             stringsAsFactors=FALSE)

Cependant, quel est le moyen le plus efficace d'initialiser un data.frame vide avec beaucoup de noms de colonnes. comme

mynames <- paste("hello", c(1:10000))

La mauvaise façon que j'ai essayée est la suivante:

df <- data.frame(mynames=numeric())

Merci beaucoup d'avance

26
Wilmer E. Henao

Peut être ça -

df <- data.frame(matrix(ncol = 10000, nrow = 0))
colnames(df) <- paste0("hello", c(1:10000))

Et la suggestion de @ joran - df <- setNames(data.frame(matrix(ncol = 10000, nrow = 0)),paste0("hello", c(1:10000)))

30
TheComeOnMan

Je le ferais avec setDF (ou setDT, si vous préférez data.table en sortie) et setnames:

library(data.table)

DF <- setnames(setDF(lapply(integer(1e4), function(...) character(0L))),
               paste0("hello", 1:1e4))
head(names(DF))
# [1] "hello1" "hello2" "hello3" "hello4" "hello5" "hello6"

Les deux étapes (setnames et setDF) sont plus efficaces que les contreparties base car aucune copie n’est créée.

Un repère:

library(microbenchmark)

microbenchmark(times = 1000,
               base = {df <- data.frame(matrix(ncol = 10000, nrow = 0))
               colnames(df) <- paste0("hello", c(1:10000))},
               DT = setnames(setDF(lapply(integer(1e4), 
                                          function(...) character(0L))),
                             paste0("hello", 1:1e4)))
# Unit: milliseconds
#  expr      min       lq     mean   median       uq      max neval cld
#  base 26.77218 30.94223 37.30173 36.76721 37.80338 102.2379  1000   b
#    DT 16.68004 23.18865 30.60573 29.18421 36.03590 178.1045  1000  a 
0
MichaelChirico