如何在不添加“Row.names”列的情况下按行名合并数据框?

Posted

技术标签:

【中文标题】如何在不添加“Row.names”列的情况下按行名合并数据框?【英文标题】:How does one merge dataframes by row name without adding a "Row.names" column? 【发布时间】:2013-06-26 21:13:58 【问题描述】:

如果我有两个数据框,比如:

df1 = data.frame(x=1:3,y=1:3,row.names=c('r1','r2','r3'))
df2 = data.frame(z=5:7,row.names=c('r5','r6','r7'))

(

R> df1
   x y
r1 1 1
r2 2 2
r3 3 3

R> df2
   z
r5 5
r6 6
r7 7

),我想按行名合并它们,保留所有内容(所以是外连接,或 all=T)。这样做:

merged.df <- merge(df1,df2,all=T,by='row.names')
R> merged.df
  Row.names  x  y  z
1        r1  1  1 NA
2        r2  2  2 NA
3        r3  3  3 NA
4        r5 NA NA  5
5        r6 NA NA  6
6        r7 NA NA  7

但我希望输入行名称是输出数据框中的行名称 (merged.df)。

我能做到:

rownames(merged.df) <- merged.df[[1]]
merged.df <- merged.df[-1]

这可行,但似乎不雅且难以记住。有人知道更清洁的方法吗?

【问题讨论】:

您的示例 data.frames 没有共同的行,这对于 merge 来说是一个非常不寻常的示例,这是故意的吗? 不是故意的,抱歉。 【参考方案1】:

merge的帮助下:

如果匹配涉及行名,一个额外的字符列称为 Row.names 添加在左侧,并且在所有情况下,结果都有 “自动”行名称。

所以很明显,至少使用merge 是无法避免Row.names 列的。但也许要删除此列,您可以按名称而不是按索引进行子集化。例如:

dd <- merge(df1,df2,by=0,all=TRUE) ## by=0 easier to write than row.names , 
                                   ## TRUE is cleaner than T

然后我使用row.names 像这样子集:

res <- subset(dd,select=-c(Row.names))
rownames(res) <- dd[,'Row.names']
  x  y  z
1  1  1 NA
2  2  2 NA
3  3  3 NA
4 NA NA  5
5 NA NA  6
6 NA NA  7

【讨论】:

【参考方案2】:

不确定是否更容易记住,但您可以使用 transform 一步完成所有操作。

transform(merge(df1,df2,by=0,all=TRUE), row.names=Row.names, Row.names=NULL)
#    x  y  z
#r1  1  1 NA
#r2  2  2 NA
#r3  3  3 NA
#r5 NA NA  5
#r6 NA NA  6
#r7 NA NA  7

【讨论】:

很好,这是within 做不到的。

以上是关于如何在不添加“Row.names”列的情况下按行名合并数据框?的主要内容,如果未能解决你的问题,请参考以下文章

将列中的值转换为现有数据框中的行名

R语言中怎么把第一列的数据作为行名

用R中定义的向量替换行名

R语言数据结构

如何按行名计算行之间的时间差并仅提取最近的行?

在没有循环的情况下按行计算 pandas 中的余弦相似度