จะเพิ่มแถวใน data frame ใน R ได้อย่างไร?


129

ใน R คุณจะเพิ่มแถวใหม่ใน data frame ได้อย่างไรเมื่อเริ่มต้น data frame แล้ว

จนถึงตอนนี้ฉันมีสิ่งนี้:

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

ความช่วยเหลือใด ๆ จะได้รับการชื่นชม


1
กำหนดชื่อให้deด้วย names(de) <- c("hello","goodbye")และrbind
Khashaa

3
หรือในบรรทัดเดียวrbind(df, setNames(de, names(df)))
Rich Scriven

2
นี่เป็นพื้นที่ที่ฐาน R ล้มเหลวอย่างน่าสังเวชและมีมานานแล้ว: stackoverflow.com/questions/13599197/…
thelatemail

1
@thelatemail ไม่เห็นด้วย เฟรมข้อมูลเป็นโครงสร้างพิเศษใน r รายชื่อรายการที่มีชื่อสลัวทั่วไปและคุณลักษณะและวิธีการ ฉันคิดว่ามันเป็นสิ่งที่คาดหวังมากว่าหนึ่งไม่ได้rbind(data.frame(a = 1), data.frame(b = 2)).. ทำไมคุณถึงต้องการ? ฉันหวังว่าจะเกิดข้อผิดพลาดโดยไม่คำนึงถึง มันเหมือนกับmerge'ing กับbyตัวแปรสุ่ม และนี่คือปี 2015 ทุกคนไม่ได้ตั้งoptions(stringsAsFactors = FALSE)?
rawr

1
@rawr - แน่นอนว่าไม่ควรผูกชื่อที่แตกต่างกัน แต่ R ไม่สามารถจัดการการผูกชื่อกับไม่มีชื่อการผูกชื่อกับไม่มีชื่อที่มีมิติเดียวกันหรือการผูกข้อมูลใหม่เพื่อรวมระดับปัจจัยใหม่ ผมคิดว่านั่นคือจุดอ่อน โดยเฉพาะอย่างยิ่งเมื่อสามารถจัดการกับชื่อที่ซ้ำกันและชื่อ NA ทั้งหมดได้ และการตั้งค่าstringsAsFactors=FALSEสามารถแก้ไขได้อย่างรวดเร็ว แต่การเปลี่ยนค่าเริ่มต้นที่คนอื่นตั้งไว้แตกต่างกันอาจทำลายวันได้อย่างแท้จริง
thelatemail

คำตอบ:


131

เช่นเดียวกับ @Khashaa และ @Richard Scriven ชี้ให้เห็นในความคิดเห็นคุณต้องตั้งชื่อคอลัมน์ที่สอดคล้องกันสำหรับกรอบข้อมูลทั้งหมดที่คุณต้องการต่อท้าย

ดังนั้นคุณจะต้องประกาศอย่างชัดแจ้งชื่อคอลัมน์สำหรับกรอบข้อมูลที่สองแล้วใช้de rbind()คุณกำหนดชื่อคอลัมน์สำหรับเฟรมข้อมูลแรกเท่านั้น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)

ขอบคุณ! มีความคิดอย่างไรที่จะแก้ไขปัญหานี้หากฉันไม่มี dataframe ที่สองที่ประกาศ แต่มีค่าแต่ละค่าที่ฉันต้องการเพิ่มลงในแถวใหม่ที่เก็บไว้เป็นตัวแปร
Rilcon42

8
ลอง: newdf<-rbind(df, data.frame(hello="hola", goodbye="ciao"))หรือด้วยตัวแปร:newdf<-rbind(df, data.frame(hello=var1, goodbye=var2))
Parfait

109

มาทำให้ง่าย:

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

10
สิ่งนี้ทำให้เกิดปัญหาเมื่อพยายามเพิ่มแถวใหม่ด้วยชนิดข้อมูลผสม (สตริงบางตัวตัวเลขบางตัว) ในกรณีนี้แม้ค่าตัวเลขจะถูกแปลงเป็นสตริง หนึ่งวิธีแก้ปัญหาคือการเพิ่มค่าแยกบางอย่างเช่นต่อไปนี้ (สมมติว่ามี 3 คอลัมน์): df[nrow(df) + 1, 1:2] = c("v1", "v2")และdf[nrow(df), 3] = 100แต่ก็ยังเป็นจุดที่ดีเกี่ยวกับการเพิ่มแถวใหม่ ดังนั้น +1
The Student Soul

17
หรือใช้ "list" แทน "c"
Ytsen de Boer

เป็นความคิดที่ดี แต่จะทำอย่างไรหากต้องการแทรกหรือเพิ่มแถวใหม่ในตำแหน่งแรก
Darwin PC

1
ลองใช้ data.table แต่การบอกด้วย nrow + 1 อยู่นอกช่วง
Herman Toothrot

1
@Arani list()มีคำตอบอยู่แล้วกับ ฉันยกเลิกการแก้ไขของคุณแล้ว
M--

41

หรือตามแรงบันดาลใจจาก @MatheusAraujo:

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

สิ่งนี้จะอนุญาตสำหรับประเภทข้อมูลผสม


24

ตอนนี้มีadd_row()จากtibbleหรือtidyverseแพ็คเกจ

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

คอลัมน์ที่ไม่ระบุจะได้รับNAไฟล์.


ฉันชอบแนวทางนี้หากคุณยึดติดกับปรัชญาที่เป็นระเบียบเรียบร้อย ไม่เช่นนั้นไวยากรณ์ R พื้นฐานเป็นทักษะการเอาตัวรอดที่มีประโยชน์เมื่อคุณอยู่ในสภาพแวดล้อมที่คุณไม่มีสิทธิ์นำเข้าแพ็คเกจ ฉันชอบคำตอบโดยใช้ไวยากรณ์ R ธรรมดาที่มีrbindและas.matrix ด้านล่าง
Pablo Adames

17

ฉันชอบlistแทนที่จะเป็นcเพราะมันจัดการประเภทข้อมูลแบบผสมได้ดีกว่า การเพิ่มคอลัมน์เพิ่มเติมในคำถามของผู้โพสต์ต้นฉบับ:

#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)

โปรดทราบว่าจำเป็นต้องมีการควบคุมเพิ่มเติมหากการแปลงสตริง / ปัจจัยมีความสำคัญ

หรือใช้ตัวแปรดั้งเดิมกับโซลูชันจาก MatheusAraujo / Ytsen de Boer:

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

โปรดทราบว่าโซลูชันนี้ใช้ไม่ได้กับสตริงเว้นแต่จะมีข้อมูลอยู่ในดาต้าเฟรม


หากhelloและgoodbyeมีลักษณะเฉพาะdfคุณสามารถทำสิ่งต่อไปนี้ได้ คุณไม่จำเป็นต้องใช้ชื่อในรายการ df <- data.frame(hello = "hi", goodbye = "bye", volume = 1,stringsAsFactors = FALSE); rbind(df, list("hola", "ciao", 100)).
jazzurro

11

ไม่หรูหรามาก แต่:

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

จากเอกสารของrbindฟังก์ชัน:

สำหรับrbindชื่อคอลัมน์จะนำมาจากอาร์กิวเมนต์แรกที่มีชื่อที่เหมาะสม: colnames สำหรับเมทริกซ์ ...


โซลูชันนี้ใช้งานได้โดยไม่จำเป็นต้องระบุคอลัมน์ที่จะเพิ่มซึ่งดีกว่ามากสำหรับแอปพลิเคชันบนชุดข้อมูลขนาดใหญ่
Phil_T

1

ฉันต้องเพิ่มstringsAsFactors=FALSEเมื่อสร้าง 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
> 

1

ตรวจสอบให้แน่ใจ stringsAsFactors=FALSEเมื่อสร้าง 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"

การไม่ใช้stringsAsFactors=FALSEเมื่อสร้าง dataframe จะทำให้เกิดข้อผิดพลาดต่อไปนี้เมื่อพยายามเพิ่มแถวใหม่:

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

0

มีวิธีที่ง่ายกว่าในการต่อท้ายระเบียนจากดาต้าเฟรมหนึ่งไปยังอีกหากคุณทราบว่าดาต้าเฟรมทั้งสองแชร์คอลัมน์และประเภทเดียวกัน ผนวกหนึ่งแถวจากxxไปyyเพียงแค่ทำต่อไปนี้ที่iเป็น'แถวในลำดับที่ixx

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

ง่ายๆแค่นั้นเอง ไม่มีการผูกยุ่ง หากคุณต้องการต่อท้ายทั้งหมดxxให้yyเรียกลูปหรือใช้ประโยชน์จากความสามารถของลำดับ R แล้วทำสิ่งนี้:

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

0

หากคุณต้องการสร้างเฟรมข้อมูลว่างและเพิ่มเนื้อหาในลูปสิ่งต่อไปนี้อาจช่วยได้:

# 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

หวังว่าจะช่วยได้ :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.