如果某些列很常见,则将数据框附加到主数据框

Append a data frame to a master data frame if some columns are common

我想将一个数据框附加到另一个数据框(主数据框)。问题是他们的列中只有一部分是常见的。此外,它们的列顺序可能不同。

主数据帧:

   a b  c
r1 1 2 -2
r2 2 4 -4
r3 3 6 -6
r4 4 8 -8

新数据框:

      d  a   c
r1 -120 10 -20
r2 -140 20 -40

预期结果:

    a   b    c
r1  1   2   -2
r2  2   4   -4
r3  3   6   -6
r4  4   8   -8
r5 10 NaN  -20
r6 20 NaN  -40

有什么聪明的方法可以做到这一点吗? This 是一个类似的问题,但设置不同。

查看 dplyr 包中的 bind_rows 函数。默认情况下,它会为您做一些好事,例如用 NA 填充存在于一个 data.frame 而另一个不存在的列,而不仅仅是失败。这是一个例子:

# Use the dplyr package for binding rows and for selecting columns
library(dplyr)

# Generate some example data
a <- data.frame(a = rnorm(10), b = rnorm(10))
b <- data.frame(a = rnorm(5), c = rnorm(5))

# Stack data frames
bind_rows(a, b)

Source: local data frame [15 x 3]

            a          b          c
1   2.2891895  0.1940835         NA
2   0.7620825 -0.2441634         NA
3   1.8289665  1.5280338         NA
4  -0.9851729 -0.7187585         NA
5   1.5829853  1.6609695         NA
6   0.9231296  1.8052112         NA
7  -0.5801230 -0.6928449         NA
8   0.2033514 -0.6673596         NA
9  -0.8576628  0.5163021         NA
10  0.6296633 -1.2445280         NA
11  2.1693068         NA -0.2556584
12 -0.1048966         NA -0.3132198
13  0.2673514         NA -1.1181995
14  1.0937759         NA -2.5750115
15 -0.8147180         NA -1.5525338

要解决您问题中的问题,您需要先 select 主 data.frame 中的列。如果 a 是主 data.frame,并且 b 包含您要添加的数据,您可以使用 dplyr 中的 select 函数来获取要添加的列你先需要。

# Select all columns in b with the same names as in master data, a
# Use select_() instead of select() to do standard evaluation.
b <- select_(b, names(a))

# Combine
bind_rows(a, b)

Source: local data frame [15 x 2]

            a          b
1   2.2891895  0.1940835
2   0.7620825 -0.2441634
3   1.8289665  1.5280338
4  -0.9851729 -0.7187585
5   1.5829853  1.6609695
6   0.9231296  1.8052112
7  -0.5801230 -0.6928449
8   0.2033514 -0.6673596
9  -0.8576628  0.5163021
10  0.6296633 -1.2445280
11  2.1693068         NA
12 -0.1048966         NA
13  0.2673514         NA
14  1.0937759         NA
15 -0.8147180         NA

试试这个:

library(plyr) # thanks to comment @ialm
df <- data.frame(a=1:4,b=seq(2,8,2),c=seq(-2,-8,-2))
new <- data.frame(d=c(-120,-140),a=c(10,20),c=c(-20,40))

# we use %in% to pull the columns that are the same in the master
# then we use rbind.fill to put in this dataframe below the master
# filling any missing data with NA values
res <- rbind.fill(df,new[,colnames(new) %in% colnames(df)])

> res
   a  b   c
1  1  2  -2
2  2  4  -4
3  3  6  -6
4  4  8  -8
5 10 NA -20
6 20 NA  40

另一个选项是使用 plyr 包中的 rbind.fill

引入您的示例数据

toread <- "
a b  c
1 2 -2
2 4 -4
3 6 -6
4 8 -8"
master <- read.table(textConnection(toread), header = TRUE) 
toread <- "
d  a   c
-120 10 -20
-140 20 -40"
to.append <- read.table(textConnection(toread), header = TRUE) 

绑定数据

library(plyr)
rbind.fill(master, to.append)

此处发布的基于 dplyrplyr 的解决方案对于分别使用 bind_rowsrbind.fill 的任务来说非常自然,尽管也可以作为基本 R 中的单行代码。基本上我会遍历第一个数据框的名称,如果第二个数据框存在,则获取相应的列,否则返回所有 NaN 值。

rbind(A, sapply(names(A), function(x) if (x %in% names(B)) B[,x] else rep(NaN, nrow(B))))
#     a   b   c
# r1  1   2  -2
# r2  2   4  -4
# r3  3   6  -6
# r4  4   8  -8
# 5  10 NaN -20
# 6  20 NaN -40