Ajouter une ligne à dataframe
Dans R, comment ajouter une nouvelle ligne à un dataframe une fois que le dataframe a déjà été initialisé?
Jusqu'à présent, 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?
8 réponses
Comme le soulignent @Khashaa et @ Richard Scriven dans les commentaires, vous devez définir des noms de colonnes cohérents pour toutes les trames de données que vous souhaitez ajouter.
Par conséquent, vous devez déclarer explicitement les noms de colonnes pour la deuxième trame de données, de
, puis utiliser rbind()
. Vous définissez uniquement les noms de colonne pour la première trame 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)
Faisons simple:
df[nrow(df) + 1,] = list("v1","v2")
Édité sur la base des commentaires. list
à la place de c
empêche les changements de classe en cas d'ajout de lignes de classe mixtes.
Ou, comme inspiré par @ MatheusAraujo:
df[nrow(df) + 1,] = list("v1","v2")
Cela permettrait des types de données mixtes.
J'aime list
au lieu de c
car il gère mieux les types de données mixtes. Ajout d'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 nécessaire 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 à moins qu'il n'y ait des données existantes dans le dataframe.
Pas terriblement élégant, mais:
data.frame(rbind(as.matrix(df), as.matrix(de)))
De la documentation de la fonction rbind
:
Pour
rbind
les noms de colonne sont tirés du premier argument avec des noms appropriés: colnames pour une matrice...
Je dois ajouter stringsAsFactors=FALSE
lors de la création du dataframe.
> 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
>
Il existe un moyen plus simple d'ajouter un enregistrement d'un dataframe à un autre si vous savez que les deux dataframes partagent les mêmes colonnes et types. Pour ajouter une ligne de xx
à yy
Il suffit de faire ce qui suit où i
est la i
'E ligne dans xx
.
yy[nrow(yy)+1,] <- xx[i,]
Aussi Simple que ça. Pas de liaisons désordonnées. Si vous devez ajouter tout xx
à yy
, appelez une boucle ou profitez des capacités de séquence de R et faites ceci:
zz[(nrow(zz)+1):(nrow(zz)+nrow(yy)),] <- yy[1:nrow(yy),]
Assurez-vous de spécifier
stringsAsFactors=FALSE
lors de la création du dataframe:
> 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 du dataframe
résultat de 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