2016-11-26 67 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