web-dev-qa-db-fra.com

Ajouter une ligne à la structure de données

Dans R, comment ajoutez-vous une nouvelle ligne à une image de données une fois que l'image de données a déjà été initialisée?

Jusqu'ici j'ai ceci:

df<-data.frame("hi","bye")
names(df)<-c("hello","goodbye")
#I am trying to add hola and ciao as a new row
de<-data.frame("hola","ciao")
merge(df,de) #adds to the same row as new columns
#I couldnt find an rbind solution that wouldnt give me an error

Des idées?

75
Rilcon42

Comme @Khashaa et @Richard Scriven dans les commentaires, vous devez définir des noms de colonne cohérents pour tous les blocs de données que vous souhaitez ajouter. 

Par conséquent, vous devez déclarer explicitement les noms des colonnes pour le deuxième cadre de données, de, puis utiliser rbind(). Vous définissez uniquement les noms de colonne pour le premier bloc de données, df:

df<-data.frame("hi","bye")
names(df)<-c("hello","goodbye")

de<-data.frame("hola","ciao")
names(de)<-c("hello","goodbye")

newdf <- rbind(df, de)
75
Parfait

Rendons les choses simples:

df[nrow(df) + 1,] = list("v1","v2")

édité en fonction des commentaires. list au lieu de c empêche les changements de classe en cas d'ajout de lignes de classe mélangées.

52
Matheus Araujo

J'aime list au lieu de c car il gère mieux les types de données mixtes. Ajouter une colonne supplémentaire à la question de l'affiche originale:

#Create an empty data frame
df <- data.frame(hello=character(), goodbye=character(), volume=double())
de <- list(hello="hi", goodbye="bye", volume=3.0)
df = rbind(df,de, stringsAsFactors=FALSE)
de <- list(hello="hola", goodbye="ciao", volume=13.1)
df = rbind(df,de, stringsAsFactors=FALSE)

Notez qu'un contrôle supplémentaire est requis si la conversion chaîne/facteur est importante.

Ou en utilisant les variables d'origine avec la solution de MatheusAraujo/Ytsen de Boer:

df[nrow(df) + 1,] = list(hello="hallo",goodbye="auf wiedersehen", volume=20.2)

Notez que cette solution ne fonctionne pas bien avec les chaînes sauf si des données existent dans le cadre de données.

9
gsk9

Pas terriblement élégant, mais:

data.frame(rbind(as.matrix(df), as.matrix(de)))

Dans la documentation de la fonction rbind:

Pour rbind, les noms de colonne sont extraits du premier argument avec les noms appropriés: noms de colonnes pour une matrice ...

8
J. Win.

Il y a maintenant add_row() parmi les packages tibble ou tidyverse.

library(tidyverse)
df %>% add_row(hello = "hola", goodbye = "ciao")

Les colonnes non spécifiées obtiennent une NA.

3
Joe

Je dois ajouter stringsAsFactors=FALSE lors de la création de la structure de données.

> df <- data.frame("hello"= character(0), "goodbye"=character(0))
> df
[1] hello   goodbye
<0 rows> (or 0-length row.names)
> df[nrow(df) + 1,] = list("hi","bye")
Warning messages:
1: In `[<-.factor`(`*tmp*`, iseq, value = "hi") :
  invalid factor level, NA generated
2: In `[<-.factor`(`*tmp*`, iseq, value = "bye") :
  invalid factor level, NA generated
> df
  hello goodbye
1  <NA>    <NA>
> 

.

> df <- data.frame("hello"= character(0), "goodbye"=character(0), stringsAsFactors=FALSE)
> df
[1] hello   goodbye
<0 rows> (or 0-length row.names)
> df[nrow(df) + 1,] = list("hi","bye")
> df[nrow(df) + 1,] = list("hola","ciao")
> df[nrow(df) + 1,] = list(hello="hallo",goodbye="auf wiedersehen")
> df
  hello         goodbye
1    hi             bye
2  hola            ciao
3 hallo auf wiedersehen
> 
1
nealei

Il existe un moyen plus simple d’ajouter un enregistrement d’un bloc de données à un autre SI vous savez que les deux blocs de données partagent les mêmes colonnes et types. Pour ajouter une ligne de xx à yy, procédez comme suit: i est la i'ème ligne de xx.

yy[nrow(yy)+1,] <- xx[i,]

Aussi simple que cela. Pas de désordre lie. Si vous devez ajouter tout xx à yy, appelez une boucle ou tirez parti des capacités de séquence de R et procédez comme suit:

zz[(nrow(zz)+1):(nrow(zz)+nrow(yy)),] <- yy[1:nrow(yy),]
0
Patrick Champion

Assurez-vous de spécifier stringsAsFactors=FALSE lors de la création de la structure de données:

> rm(list=ls())
> trigonometry <- data.frame(character(0), numeric(0), stringsAsFactors=FALSE)
> colnames(trigonometry) <- c("theta", "sin.theta")
> trigonometry
[1] theta     sin.theta
<0 rows> (or 0-length row.names)
> trigonometry[nrow(trigonometry) + 1, ] <- c("0", sin(0))
> trigonometry[nrow(trigonometry) + 1, ] <- c("pi/2", sin(pi/2))
> trigonometry
  theta sin.theta
1     0         0
2  pi/2         1
> typeof(trigonometry)
[1] "list"
> class(trigonometry)
[1] "data.frame"

Ne pas utiliser stringsAsFactors=FALSE lors de la création de la structure de données entraînera l'erreur suivante lors de la tentative d'ajout de la nouvelle ligne:

> trigonometry[nrow(trigonometry) + 1, ] <- c("0", sin(0))
Warning message:
In `[<-.factor`(`*tmp*`, iseq, value = "0") :
  invalid factor level, NA generated
0
OracleJavaNet