Bagaimana cara menambahkan baris ke bingkai data di R?

129

Di R, bagaimana Anda menambahkan baris baru ke bingkai data setelah bingkai data telah diinisialisasi?

Sejauh ini saya punya ini:

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

Bantuan apa pun akan dihargai

Rilcon42
sumber
1
menetapkan nama dejuga. names(de) <- c("hello","goodbye")danrbind
Khashaa
3
Atau dalam satu barisrbind(df, setNames(de, names(df)))
Rich Scriven
2
Ini benar-benar adalah area yang membuat R gagal total, dan sudah lama: stackoverflow.com/questions/13599197/…
thelatemail
1
@thelatemail tidak setuju. frame data adalah struktur khusus dalam r. daftar daftar dengan nama dan atribut dan metode yang sama. Saya pikir sangat diharapkan bahwa seseorang tidak bisa rbind(data.frame(a = 1), data.frame(b = 2)).. mengapa Anda mau? Saya berharap itu akan membuat kesalahan terlepas. Ini seperti mergemenggunakan byvariabel acak . Dan ini tahun 2015, bukankah semua orang menetapkan options(stringsAsFactors = FALSE)?
rawr
1
@rawr - tentu saja, nama-nama yang berbeda tidak boleh diikat, tetapi R tidak dapat menangani pengikatan tidak ada nama tanpa nama, mengikat nama tanpa nama dengan dimensi yang sama, atau mengikat data baru untuk memasukkan tingkat faktor baru. Saya pikir itu kelemahan. Terutama ketika itu dapat menangani pengikatan nama yang diulang dan semua nama NA. Dan pengaturan stringsAsFactors=FALSEdapat menjadi perbaikan cepat, tetapi mengubah default yang diatur orang lain secara berbeda dapat benar-benar merusak sehari.
thelatemail

Jawaban:

131

Seperti yang ditunjukkan oleh @Khashaa dan @Richard Scriven dalam komentar, Anda harus menetapkan nama kolom yang konsisten untuk semua bingkai data yang ingin Anda tambahkan.

Karenanya, Anda harus secara eksplisit mendeklarasikan nama kolom untuk bingkai data kedua de,, lalu gunakan rbind(). Anda hanya mengatur nama kolom untuk data frame pertama, 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)
Parfait
sumber
Terima kasih! Adakah yang tahu bagaimana cara memperbaikinya jika saya tidak memiliki dataframe kedua yang dideklarasikan, tetapi apakah masing-masing memiliki nilai yang ingin saya tambahkan ke baris baru yang disimpan sebagai variabel?
Rilcon42
8
Coba: newdf<-rbind(df, data.frame(hello="hola", goodbye="ciao"))ATAU dengan variabel:newdf<-rbind(df, data.frame(hello=var1, goodbye=var2))
Parfait
109

Mari kita membuatnya sederhana:

df[nrow(df) + 1,] = c("v1","v2")
Matheus Araujo
sumber
10
Ini menyebabkan masalah ketika mencoba menambahkan baris baru dengan tipe data campuran (beberapa string, beberapa numerik). Dalam kasus seperti itu, bahkan nilai numerik dikonversi ke string. Salah satu solusinya adalah menambahkan nilai secara terpisah, kira-kira seperti berikut (dengan asumsi ada 3 kolom): df[nrow(df) + 1, 1:2] = c("v1", "v2")dan df[nrow(df), 3] = 100Tapi tetap saja itu poin bagus tentang menambahkan baris baru. Jadi, +1
The Student Soul
17
Atau gunakan "daftar" alih-alih "c".
Ytsen de Boer
ide yang bagus, tetapi bagaimana saya bisa melakukannya jika saya ingin memasukkan atau menambahkan baris baru pada posisi pertama?
Darwin PC
1
Mencoba ini dengan data.table tetapi memberitahu dengan nrow + 1 berada di luar jangkauan.
Herman Toothrot
1
@ Arani sudah ada jawabannya list(). Saya mengembalikan suntingan Anda.
M
41

Atau, seperti yang terinspirasi oleh @MatheusAraujo:

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

Ini akan memungkinkan untuk tipe data campuran.

Ytsen de Boer
sumber
24

Ada sekarang add_row()dari paket tibbleatau tidyverse.

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

Kolom yang tidak ditentukan mendapatkan NA.

Joe
sumber
Saya menyukai pendekatan ini jika Anda tetap pada filosofi rapi. Kalau tidak, sintaks R dasar adalah keterampilan bertahan hidup yang berguna ketika Anda berada di lingkungan di mana Anda tidak memiliki hak istimewa untuk mengimpor paket. Saya sangat suka jawabannya menggunakan sintaks R polos dengan rbinddan di as.matrix bawah ini
Pablo Adames
17

Saya suka listbukan ckarena menangani tipe data campuran lebih baik. Menambahkan kolom tambahan ke pertanyaan pengirim asli:

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

Perhatikan bahwa beberapa kontrol tambahan diperlukan jika konversi string / faktor penting.

Atau menggunakan variabel asli dengan solusi dari MatheusAraujo / Ytsen de Boer:

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

Perhatikan bahwa solusi ini tidak bekerja dengan baik dengan string kecuali ada data yang ada di dalam kerangka data.

gsk9
sumber
Jika hellodan goodbyedalam karakter dalam df, Anda dapat melakukan hal berikut. Anda tidak perlu menggunakan nama dalam daftar. df <- data.frame(hello = "hi", goodbye = "bye", volume = 1,stringsAsFactors = FALSE); rbind(df, list("hola", "ciao", 100)).
jazzurro
11

Tidak terlalu anggun, tapi:

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

Dari dokumentasi rbindfungsi:

Untuk rbindnama-nama kolom diambil dari argumen pertama dengan nama-nama yang sesuai: nama-nama untuk matriks ...

J. Win.
sumber
Solusi ini berfungsi tanpa perlu menentukan kolom yang akan ditambahkan, yang jauh lebih baik untuk aplikasi pada dataset besar
Phil_T
1

Saya perlu menambahkan stringsAsFactors=FALSEsaat membuat kerangka data.

> 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
> 
nealei
sumber
1

Pastikan untuk menentukan stringsAsFactors=FALSEkapan membuat bingkai data:

> 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"

Gagal digunakan stringsAsFactors=FALSEsaat membuat kerangka data akan menghasilkan kesalahan berikut saat mencoba menambahkan baris baru:

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

Ada cara yang lebih sederhana untuk menambahkan catatan dari satu kerangka data ke kerangka data lain JIKA Anda tahu bahwa kedua kerangka data tersebut berbagi kolom dan jenis yang sama. Untuk menambahkan satu baris dari xxke yyhanya melakukan berikut di mana iadalah i'th baris dalam xx.

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

Sederhana seperti itu. Tidak ada ikatan yang berantakan. Jika Anda perlu menambahkan semua xxuntuk yy, maka panggil satu lingkaran atau manfaatkan kemampuan urutan R dan lakukan ini:

zz[(nrow(zz)+1):(nrow(zz)+nrow(yy)),] <- yy[1:nrow(yy),]
Patrick Champion
sumber
0

Jika Anda ingin membuat bingkai data kosong dan menambahkan konten dalam satu lingkaran, hal berikut ini dapat membantu:

# 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

Semoga bermanfaat :)

Edwin Pratt
sumber