R'de bir veri çerçevesine nasıl satır eklenebilir?


129

R'de, veri çerçevesi zaten başlatıldıktan sonra bir veri çerçevesine yeni bir satırı nasıl eklersiniz?

Şimdiye kadar şuna sahibim:

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

Herhangi bir yardım takdir edilecektir


1
da isimler atayın de. names(de) <- c("hello","goodbye")verbind
Khashaa

3
Veya tek satırdarbind(df, setNames(de, names(df)))
Rich Scriven

2
Bu gerçekten temel R'nin sefil bir şekilde başarısız olduğu ve uzun süredir sahip olduğu bir alandır: stackoverflow.com/questions/13599197/…
theelatemail

1
@thelatemail katılmıyorum. veri çerçeveleri r'de özel bir yapıdır. ortak dimnames ve öznitelikleri ve yöntemleri içeren listelerin listesi. Birinin yapamayacağı çok bekleniyor rbind(data.frame(a = 1), data.frame(b = 2)).. neden istesin ki? Umarım bu bir hata olur. Sanki merge'rastgele ile ing bydeğişken. Ve bu 2015, herkes hazır değil options(stringsAsFactors = FALSE)mi?
rawr

1
@rawr - elbette, farklı adlar bağlı olmamalıdır, ancak R hiçbir adın adlara bağlanmasını, adları aynı boyutlara sahip olmayan adlara bağlamayı veya yeni faktör düzeylerini dahil etmek için yeni verileri bağlamayı işleyemez. Bunun bir zayıflık olduğunu düşünüyorum. Özellikle, tekrarlanan isimleri ve tüm NA isimlerini birleştirebildiği zaman. Ve ayar stringsAsFactors=FALSEhızlı bir düzeltme olabilir, ancak diğer insanların farklı şekilde ayarlayacağı varsayılanları değiştirmek gerçekten bir günü mahvedebilir.
thelatemail

Yanıtlar:


131

@ Khashaa ve @Richard Scriven'in yorumlarda belirttiği gibi, eklemek istediğiniz tüm veri çerçeveleri için tutarlı sütun adları belirlemeniz gerekir.

Bu nedenle, ikinci veri çerçevesi için sütun adlarını açıkça belirtmeniz ve deardından kullanmanız gerekir rbind(). Yalnızca ilk veri çerçevesi için sütun adlarını ayarlarsınız 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)

Teşekkürler! İkinci bir veri çerçevem ​​yoksa, bunun yerine değişken olarak depolanan yeni bir satıra eklemek istediğim her bir değeri varsa, bunu nasıl düzelteceğime dair bir fikriniz var mı?
Rilcon42

8
Deneyin: newdf<-rbind(df, data.frame(hello="hola", goodbye="ciao"))VEYA değişkenle:newdf<-rbind(df, data.frame(hello=var1, goodbye=var2))
Parfait

109

Basitleştirelim:

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

10
Bu, karışık veri türleri (bazı dizeler, bazıları sayısal) içeren yeni bir satır eklemeye çalışırken sorunlara neden olur. Böyle bir durumda sayısal değerler bile dizeye dönüştürülür. Bir geçici çözüm, değerleri ayrı ayrı eklemektir, aşağıdaki gibi (3 sütun olduğu varsayılarak): df[nrow(df) + 1, 1:2] = c("v1", "v2")Ve df[nrow(df), 3] = 100yine de yeni satır eklemenin iyi bir noktasıdır. Öyleyse, +1
The Student Soul

17
Veya "c" yerine "liste" yi kullanın.
Ytsen de Boer

güzel fikir, ama ilk konuma yeni bir satır eklemek veya eklemek istersem nasıl yapabilirim?
Darwin PC

1
Bunu data.table ile denedim, ancak nrow + 1'in aralık dışında olduğunu söylüyor.
Herman Toothrot

1
@Arani ile zaten bir cevap var list(). Düzenlemenizi geri aldım.
2019

41

Veya @MatheusAraujo'dan ilham aldığı gibi:

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

Bu, karışık veri türlerine izin verir.


24

Şimdi var add_row()dan tibbleveya tidyversepaketler.

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

Belirtilmemiş sütunlar bir NA.


Tidyverse felsefesine bağlı kalırsanız bu yaklaşımı sevdim. Aksi takdirde, temel R sözdizimi, paketleri içe aktarma ayrıcalıklarına sahip olmadığınız bir ortamdayken kullanışlı olan bir hayatta kalma becerisidir. Yanıtı özellikle düz R sözdizimi kullanarak rbindve as.matrix aşağıda
Pablo Adames

17

Bunun listyerine, ckarışık veri türlerini daha iyi işlediği için seviyorum . Orijinal göndericinin sorusuna ek bir sütun eklemek:

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

Dizi / faktör dönüşümü önemliyse bazı ek kontrollerin gerekli olduğunu unutmayın.

Veya MatheusAraujo / Ytsen de Boer'in çözümüyle orijinal değişkenleri kullanarak:

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

Veri çerçevesinde mevcut veriler olmadıkça bu çözümün dizelerle iyi çalışmadığını unutmayın.


Eğer hellove goodbyekarakter dfiçindeyseniz, aşağıdakileri yapabilirsiniz. Bir listede mutlaka isim kullanmanız gerekmez. df <- data.frame(hello = "hi", goodbye = "bye", volume = 1,stringsAsFactors = FALSE); rbind(df, list("hola", "ciao", 100)).
jazzurro

11

Çok zarif değil ama:

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

rbindFonksiyonun dokümantasyonundan :

rbindSütun isimleri için uygun isimlerle ilk bağımsız değişkenden alınır: bir matris için sütun isimleri ...


Bu çözüm, eklenecek sütunların belirtilmesine gerek kalmadan çalışır, bu da büyük veri kümelerindeki uygulamalar için çok daha iyidir
Phil_T

1

Ben eklemeniz gerekir stringsAsFactors=FALSEdataframe oluştururken.

> 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

Belirtmek için emin olun stringsAsFactors=FALSEdataframe oluştururken:

> 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=FALSEVeri çerçevesini oluştururken kullanılmaması , yeni satırı eklemeye çalışırken aşağıdaki hataya neden olur:

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

0

İki veri çerçevesinin aynı sütunları ve türleri paylaştığını biliyorsanız, bir veri çerçevesinden diğerine kayıt eklemenin daha basit bir yolu vardır. Dan bir satır eklemek için xxiçin yysadece aşağıdakileri yapmanız iolduğu iiçinde 'inci satır xx.

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

Bu kadar basit. Dağınık bağ yok. Eğer tüm eklemek gerekirse xxetmek yy, ardından ya bir döngü arayabilir veya R'ın dizisi yeteneklerini yararlanmak ve bunu:

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

0

Boş bir veri çerçevesi oluşturmak ve bir döngüde içerik eklemek istiyorsanız, aşağıdakiler yardımcı olabilir:

# 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

Umarım yardımcı olur :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.