2016-11-26 72 views
0

所以,我怎么可以添加两个数据帧,其中行添加相同row.names:添加两个data.frames,使用rownames索引

x = data.frame(x = 1:10, y = 10:1); y = x 
rownames(y) = as.numeric(rownames(x)) + 5 

x + y #WRONG, rows should be offset by '5', producing a data.frame that has 15 rows. 

也许可以做到这一点使用ddply,通过添加索引列,这样的(这也显示我想要的结果):

x$id = as.numeric(rownames(x)) 
y$id = as.numeric(rownames(y)) 
plyr::ddply(rbind(x,y),'id',function(x){ 
    colSums(x[,c('x','y')]) 
})[,-1] 

目标结果:

x y 
1 1 10 
2 2 9 
3 3 8 
4 4 7 
5 5 6 
6 7 15 
7 9 13 
8 11 11 
9 13 9 
10 15 7 
11 6 5 
12 7 4 
13 8 3 
14 9 2 
15 10 1 

在上文中,行6 :10是由索引列相交的两个数据帧的交集的总和。

+1

这似乎更像'join'而不是'add'。我强烈建议不要依靠行名进行多少计算;有些软件包(例如'dplyr')忽略/删除它们,就像它一样,或者离开它。好像你在使用行名称作为索引,那么为什么不显式添加一列,比如'$ id'?在这种情况下,您可以使用许多连接技术之一,例如'x $ id < - 1:10; y $ id < - 6:15; dplyr :: bind_rows(x,dplyr :: anti_join(y,x,by =“id”))'。 – r2evans

+1

这样使用像merge这样的合并(x,y,by = 0,all = TRUE)可以更容易处理。 –

+0

人们猜到了你想要的东西,但它绝对不会增加。请考虑扩大,使您的问题更清晰。投票结束。 – marbel

回答

2
# I would use aggregate 
d <- aggregate(rbind.data.frame(x, y), 
       list(rowname = c(rownames(x), rownames(y))), 
       sum) 
# if you want the rows ordered as before 
d <- d[order(as.numeric(d$rowname)), ] 

# rowname x y 
# 1  1 1 10 
# 8  2 2 9 
# 9  3 3 8 
# 10  4 4 7 
# 11  5 5 6 
# 12  6 7 15 
# 13  7 9 13 
# 14  8 11 11 
# 15  9 13 9 
# 2  10 15 7 
# 3  11 6 5 
# 4  12 7 4 
# 5  13 8 3 
# 6  14 9 2 
# 7  15 10 1 
4

尝试这个 -

a <- rownames(x) 
b <- rownames(y) 
rbind(x[!(a %in% b),], x[intersect(a, b),] + 
     y[intersect(a, b),], y[!(b %in% a),]) 
+0

这很好... –

1

您可以通过该行的名称是一般不建议合并。然后你得到相同的x和y的指数并且取一行数。

xx=merge(x, y, by=0, all=TRUE) 
l=lapply(names(x), function(yy) grep(paste('^',yy,'.*', sep = ''), names(xx))) 
df=as.data.frame(sapply(l, function(yy) rowSums(xx[,yy], na.rm = T))) 
names(df)=names(x) 
df[order(as.numeric(xx$Row.names)),] 

    x y 
1 1 10 
8 2 9 
9 3 8 
10 4 7 
11 5 6 
12 7 15 
13 9 13 
14 11 11 
15 13 9 
2 15 7 
3 6 5 
4 7 4 
5 8 3 
6 9 2 
7 10 1