583 votes

Créer un data.frame vide

J'essaie d'initialiser un data.frame sans aucune ligne. En fait, je veux spécifier les types de données pour chaque colonne et les nommer, mais aucune ligne n'est créée à la suite de cette opération.

Le mieux que j'ai pu faire jusqu'à présent est quelque chose comme :

df <- data.frame(Date=as.Date("01/01/2000", format="%m/%d/%Y"), 
                 File="", User="", stringsAsFactors=FALSE)
df <- df[-1,]

Cela crée un data.frame avec une seule ligne contenant tous les types de données et les noms de colonnes que je voulais, mais crée également une ligne inutile qui doit ensuite être supprimée.

Y a-t-il une meilleure façon de procéder ?

771voto

digEmAll Points 24336

Il suffit de l'initialiser avec des vecteurs vides :

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

Voici un autre exemple avec différents types de colonnes :

df <- data.frame(Doubles=double(),
                 Ints=integer(),
                 Factors=factor(),
                 Logicals=logical(),
                 Characters=character(),
                 stringsAsFactors=FALSE)

str(df)
> str(df)
'data.frame':   0 obs. of  5 variables:
 $ Doubles   : num 
 $ Ints      : int 
 $ Factors   : Factor w/ 0 levels: 
 $ Logicals  : logi 
 $ Characters: chr 

N.B. :

Initialisation d'un data.frame avec une colonne vide du mauvais type n'empêche pas les ajouts ultérieurs de lignes ayant des colonnes de types différents.
Cette méthode est juste un peu plus sûr dans le sens où vous aurez les types de colonnes corrects dès le début, donc si votre code repose sur la vérification des types de colonnes, il fonctionnera même avec un fichier de type data.frame avec zéro ligne.

3 votes

Est-ce que ce serait la même chose si j'initialisais tous les champs avec NULL ?

10 votes

@yosukesabai : non, si vous initialisez une colonne avec NULL la colonne ne sera pas ajoutée :)

0 votes

Je vois ça... pourquoi j'ai pensé que ça marcherait... ? Cela signifie donc que je dois connaître le type de données de chaque colonne à l'avance et l'initialiser correctement ?

196voto

toto_tico Points 2014

Si vous avoir déjà un cadre de données existant Disons que df qui a les colonnes que vous voulez, alors vous pouvez simplement créer un cadre de données vide en supprimant toutes les lignes :

empty_df = df[FALSE,]

Remarquez que df contient toujours les données, mais empty_df ne le fait pas.

J'ai trouvé cette question en cherchant comment créer une nouvelle instance avec des lignes vides, je pense donc qu'elle pourrait être utile pour certaines personnes.

2 votes

Une idée merveilleuse. Ne gardez aucune des lignes, mais TOUTES les colonnes. Celui qui a rétrogradé a raté quelque chose.

1 votes

Bonne solution, mais je me suis aperçu que j'obtenais un cadre de données avec 0 ligne. Afin de conserver la taille du cadre de données, je suggère new_df = df[NA,]. Cela permet également de stocker toute colonne précédente dans le nouveau cadre de données. Par exemple, pour obtenir la colonne "Date" à partir du df original (tout en gardant le reste NA) : new_df$Date <- df$Date.

2 votes

@Katya, si vous le faites df[NA,] cela affectera également l'index (ce qui n'est probablement pas ce que vous voulez), j'utiliserais plutôt df[TRUE,] = NA Cependant, notez que cela écrasera l'original. Vous devrez d'abord copier le cadre de données. copy_df = data.frame(df) et ensuite copy_df[TRUE,] = NA

87voto

zeleniy Points 393

Vous pouvez le faire sans spécifier les types de colonnes

df = data.frame(matrix(vector(), 0, 3,
                dimnames=list(c(), c("Date", "File", "User"))),
                stringsAsFactors=F)

4 votes

Dans ce cas, les types de colonnes sont par défaut logiques par vector(), mais sont ensuite remplacés par les types des éléments ajoutés à df. Essayer str(df), df[1,1]<-'x'

68voto

Floo0 Points 1475

Vous pourriez utiliser read.table avec une chaîne vide pour l'entrée text comme suit :

colClasses = c("Date", "character", "character")
col.names = c("Date", "File", "User")

df <- read.table(text = "",
                 colClasses = colClasses,
                 col.names = col.names)

Alternativement, en spécifiant l'option col.names comme une chaîne de caractères :

df <- read.csv(text="Date,File,User", colClasses = colClasses)

Merci à Richard Scriven pour l'amélioration

4 votes

Ou même read.table(text = "", ...) de sorte que vous n'avez pas besoin d'ouvrir explicitement une connexion.

1 votes

Snazzy. C'est probablement la façon la plus extensible/automatisable de faire cela pour beaucoup de colonnes potentielles

3 votes

El read.csv Cette approche fonctionne également avec readr::read_csv , comme dans read_csv("Date,File,User\n", col_types = "Dcc") . De cette façon, vous pouvez créer directement un tibble vide de la structure requise.

50voto

Daniel Fischer Points 553

Il suffit de déclarer

table = data.frame()

quand vous essayez de rbind la première ligne, il créera les colonnes

2 votes

Cela ne répond pas vraiment aux exigences de l'OP : "Je veux spécifier les types de données pour chaque colonne et les nommer". Si l'étape suivante est un rbind cela fonctionnerait bien, sinon...

1 votes

Quoi qu'il en soit, merci pour cette solution simple. Je voulais aussi initialiser un data.frame avec des colonnes spécifiques car je pensais que rbind ne pouvait être utilisé que si les colonnes correspondent entre les deux data.frame. Il semble que ce ne soit pas le cas. J'ai été surpris de pouvoir initialiser aussi simplement un data.frame en utilisant rbind. Merci.

7 votes

La meilleure solution proposée ici. Pour moi, l'utilisation de la solution proposée a fonctionné parfaitement avec rbind() .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X