Hoe kan een rij worden toegevoegd aan een dataframe in R?

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 tibbleof tidyversepakketten.

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

Niet-gespecificeerde kolommen krijgen een NA.


Antwoord 5, autoriteit 12%

Ik hou van listin plaats van comdat 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 rbindworden 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=FALSEtoevoegen 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=FALSEbij 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=FALSEniet 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 xxtoe te voegen aan yydoet u het volgende, waarbij ide ide rij is in xx.

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

Zo simpel is het. Geen rommelige bindingen. Als je alle xxmoet 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

LEAVE A REPLY

Please enter your comment!
Please enter your name here

five − 3 =

Other episodes