2015-12-14 66 views
5

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

主数据框:

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是一个类似的问题,但设置是不同的。

回答

6

查看dplyr包中的bind_rows函数。默认情况下,它会为你做一些很好的事情,比如填写一个data.frame中的列,但不是其他的NAs,而不仅仅是失败。这里有一个例子:

# 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.58-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 

要在你的问题解决问题,你想选择在主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.58-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 
2

试试这个:

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 
1

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

带给您的样本数据

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) 
+1

如果您使用'dplyr',为什么不直接使用'bind_rows()'? – ialm

+1

@ialm更仔细的阅读,这个答案*不使用任何'dplyr'函数(它只是加载包)。值得注意的是,在加载'dplyr'后加载'plyr' *将会用'plyr'版本掩盖'dplyr :: summarize'和'dplyr :: mutate',不推荐使用。 – Gregor

+1

@Gregor是的,我现在明白了。出于你在注释中突出显示的原因,如果你在'dplyr'后面加载'plyr',我会发出一个警告,我相信Hadley建议你在'dplyr'之前加载'plyr',如果你需要使用这两个软件包的话。 – ialm

2

这里发布的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 
相关问题