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?
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)
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.
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.
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 ...
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
.
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
>
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),]
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