如何在R中的数据框中添加一行?


129

在R中,一旦数据帧已经初始化,如何将新行添加到数据帧?

到目前为止,我有这个:

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
也分配名称denames(de) <- c("hello","goodbye")rbind
Khashaa,2015年

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使用随机by变量进行ing 。这是2015年,不是每个人都准备好了吗options(stringsAsFactors = FALSE)
rawr 2015年

1
@rawr-当然,不应该绑定不同的名称,但是R不能将没有名称绑定到没有名称,没有名称绑定到没有相同尺寸的名称,或者绑定新数据以合并新的因子水平。我认为这是一个缺点。特别是当它可以处理绑定的重复名称和所有NA名称时。设置stringsAsFactors=FALSE可以快速解决,但是更改其他人将要设置的默认设置确实会浪费一天的时间。
thelatemail 2015年

Answers:


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)

谢谢!如果我没有声明第二个数据框,而是想将要添加到新行中的每个值都存储为变量,是否知道如何解决此问题?
Rilcon42

8
试试:newdf<-rbind(df, data.frame(hello="hola", goodbye="ciao"))或使用变数:newdf<-rbind(df, data.frame(hello=var1, goodbye=var2))
冻糕2015年

108

让我们简单点:

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

9
尝试添加具有混合数据类型(某些字符串,某些数字)的新行时,这会导致问题。在这种情况下,即使数值也会转换为字符串。一种解决方法是分别添加值,如下所示(假定有3列):df[nrow(df) + 1, 1:2] = c("v1", "v2")并且df[nrow(df), 3] = 100但是添加新行仍然是一个好方法。因此,+ 1
学生灵魂

17
或使用“列表”代替“ c”。
伊森·德布尔

好主意,但是如果我想在第一个位置插入或添加新行怎么办?
达尔文PC

1
用data.table尝试过这个,但是用nrow + 1判断超出范围。
Herman Toothrot,

1
@Arani已经有了一个答案list()。我还原了您的修改。
M–

41

或者,受@MatheusAraujo的启发:

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

这将允许混合数据类型。


24

现在add_row()来自tibbletidyverse包。

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

未指定的列会显示NA


如果您坚持整洁的哲学,我会喜欢这种方法。否则,基本R语法是一种生存技能,当您在没有特权导入包的环境中时,它会派上用场。我特别喜欢在R rbindas.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)

请注意,除非数据框中存在现有数据,否则此解决方案不适用于字符串。


如果hellogoodbye中的字符df,您可以执行以下操作。您不必在列表中使用名称。df <- data.frame(hello = "hi", goodbye = "bye", volume = 1,stringsAsFactors = FALSE); rbind(df, list("hola", "ciao", 100))
jazzurro19年

11

不是很优雅,但是:

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

rbind功能文档中:

对于rbind列名,请从具有适当名称的第一个参数中获取:矩阵的列名...


此解决方案无需指定要添加的列即可工作,这对于大型数据集上的应用程序要好得多
Phil_T

1

stringsAsFactors=FALSE创建数据框时需要添加。

> 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在创建数据框时指定 :

> 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尝试添加新行时未能使用该数据框将导致以下错误:

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

0

如果您知道两个数据帧共享相同的列和类型,则有一种更简单的方法将记录从一个数据帧追加到另一个数据帧。要从中追加一行xxyy只需执行以下操作,其中ii第th行xx

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

就那么简单。没有凌乱的约束。如果您需要将所有内容附加xxyy,则可以调用循环或利用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

希望能帮助到你 :)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.