Hoe voegt u in R een nieuwe rij toe aan een dataframe nadat het dataframe al is geïnitialiseerd?
Tot nu toe heb ik dit:
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
# Unfortunately, I couldn't find an rbind() solution that wouldn't give me an error
Alle hulp wordt op prijs gesteld
Antwoord 1, autoriteit 100%
Zoals @Khashaa en @Richard Scriven in opmerkingen aangeven, moet u consistente kolomnamen instellen voor alle gegevensframes die u wilt toevoegen.
Daarom moet je de kolomnamen expliciet declareren voor het tweede dataframe, de
, en vervolgens rbind()
gebruiken. U stelt alleen kolomnamen in voor het eerste dataframe, 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)
Antwoord 2, autoriteit 95%
Laten we het simpel houden:
df[nrow(df) + 1,] = c("v1","v2")
Antwoord 3, autoriteit 32%
Of, zoals geïnspireerd door @MatheusAraujo:
df[nrow(df) + 1,] = list("v1","v2")
Dit zou gemengde gegevenstypen mogelijk maken.
Antwoord 4, autoriteit 29%
Er is nu add_row()
uit de tibble
of tidyverse
pakketten.
library(tidyverse)
df %>% add_row(hello = "hola", goodbye = "ciao")
Niet-gespecificeerde kolommen krijgen een NA
.
Antwoord 5, autoriteit 12%
Ik hou van list
in plaats van c
omdat het beter omgaat met gemengde gegevenstypen. Een extra kolom toevoegen aan de vraag van de originele poster:
#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)
Houd er rekening mee dat er wat extra controle nodig is als de string/factor-conversie belangrijk is.
Of gebruik de originele variabelen met de oplossing van MatheusAraujo/Ytsen de Boer:
df[nrow(df) + 1,] = list(hello="hallo",goodbye="auf wiedersehen", volume=20.2)
Houd er rekening mee dat deze oplossing niet goed werkt met de tekenreeksen, tenzij er bestaande gegevens in het dataframe zijn.
Antwoord 6, autoriteit 8%
Niet erg elegant, maar:
data.frame(rbind(as.matrix(df), as.matrix(de)))
Uit documentatie van de functie rbind
:
Voor
rbind
worden kolomnamen overgenomen uit het eerste argument met de juiste namen: colnamen voor een matrix…
Antwoord 7, autoriteit 2%
Als u een leeg gegevensframe wilt maken en inhoud in een lus wilt toevoegen, kan het volgende helpen:
# Number of students in class
student.count <- 36
# Gather data about the students
student.age <- sample(14:17, size = student.count, replace = TRUE)
student.gender <- sample(c('male', 'female'), size = student.count, replace = TRUE)
student.marks <- sample(46:97, size = student.count, replace = TRUE)
# Create empty data frame
student.data <- data.frame()
# Populate the data frame using a for loop
for (i in 1 : student.count) {
# Get the row data
age <- student.age[i]
gender <- student.gender[i]
marks <- student.marks[i]
# Populate the row
new.row <- data.frame(age = age, gender = gender, marks = marks)
# Add the row
student.data <- rbind(student.data, new.row)
}
# Print the data frame
student.data
Hopelijk helpt het 🙂
Antwoord 8
Ik moet stringsAsFactors=FALSE
toevoegen bij het maken van het 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
>
Antwoord 9
Zorg ervoor dat u opgeeft
stringsAsFactors=FALSE
bij het maken van het 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"
Als u stringsAsFactors=FALSE
niet gebruikt bij het maken van het dataframe,
resulteren in de volgende fout bij een poging om de nieuwe rij toe te voegen:
> trigonometry[nrow(trigonometry) + 1, ] <- c("0", sin(0))
Warning message:
In `[<-.factor`(`*tmp*`, iseq, value = "0") :
invalid factor level, NA generated
Antwoord 10
Er is een eenvoudigere manier om een record van het ene dataframe naar het andere toe te voegen ALS je weet dat de twee dataframes dezelfde kolommen en typen delen. Om een rij van xx
toe te voegen aan yy
doet u het volgende, waarbij i
de i
de rij is in xx
.
yy[nrow(yy)+1,] <- xx[i,]
Zo simpel is het. Geen rommelige bindingen. Als je alle xx
moet toevoegen aan yy
, roep dan een lus aan of maak gebruik van de reeksmogelijkheden van R en doe dit:
zz[(nrow(zz)+1):(nrow(zz)+nrow(yy)),] <- yy[1:nrow(yy),]
Antwoord 11
Om te formaliseren waarvoor iemand anders setNames heeft gebruikt:
add_row <- function(original_data, new_vals_list){
# appends row to dataset while assuming new vals are ordered and classed appropriately.
# new_vals must be a list not a single vector.
rbind(
original_data,
setNames(data.frame(new_vals_list), colnames(original_data))
)
}
Het behoudt klasse als het legaal is en geeft fouten elders door.
m <- mtcars[ ,1:3]
m$cyl <- as.factor(m$cyl)
str(m)
#'data.frame': 32 obs. of 3 variables:
# $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# $ cyl : Factor w/ 3 levels "4","6","8": 2 2 1 2 3 2 3 1 1 2 ...
# $ disp: num 160 160 108 258 360 ...
Factor behouden bij het toevoegen van 4, ook al werd het doorgegeven als een numeriek.
str(add_row(m, list(20,4,160)))
#'data.frame': 33 obs. of 3 variables:
# $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# $ cyl : Factor w/ 3 levels "4","6","8": 2 2 1 2 3 2 3 1 1 2 ...
# $ disp: num 160 160 108 258 360 ...
Pogingen om een niet- 4,6,8 te halen, zou een fout opleveren dat het factorniveau ongeldig is.
str(add_row(m, list(20,3,160)))
# 'data.frame': 33 obs. of 3 variables:
# $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# $ cyl : Factor w/ 3 levels "4","6","8": 2 2 1 2 3 2 3 1 1 2 ...
# $ disp: num 160 160 108 258 360 ...
Warning message:
In `[<-.factor`(`*tmp*`, ri, value = 3) :
invalid factor level, NA generated