合并具有多个行名的数据帧==NA';s在R

合并具有多个行名的数据帧==NA';s在R,r,merge,R,Merge,我想合并以下数据,data1和data2 > data1 A B C D E F alpha "Jenna" "1" "50" "60" "7" "1" <NA> NA NA "67" "99" NA NA <NA> NA NA "55" NA NA NA <NA> NA NA "45" NA NA NA beta "Jenna"

我想合并以下数据,data1和data2

> data1 
      A       B   C     D    E   F  
alpha "Jenna" "1" "50"  "60" "7" "1"
<NA>  NA      NA  "67"  "99" NA  NA 
<NA>  NA      NA  "55"  NA   NA  NA 
<NA>  NA      NA  "45"  NA   NA  NA 
beta  "Jenna" "1" "333" "89" "8" "1"
<NA>  NA      NA  "755" "74" NA  NA 
<NA>  NA      NA  "433" NA   NA  NA 
<NA>  NA      NA  "300" NA   NA  NA 

> data2
      A      B   C     D     E    F  
alpha "Lena" "1" "23"  "77"  "7"  "1"
<NA>  NA     NA  "67"  "103" NA   NA 
<NA>  NA     NA  "55"  NA    NA   NA  # note here only have 2 rows but 3 above
deta  "Lena" "1" "599" "9"   "76" "1" #note this one is deta not beta 
<NA>  NA     NA  "763" "88"  NA   NA 
<NA>  NA     NA  "1"   NA    NA   NA 
<NA>  NA     NA  "3"   NA    NA   NA 

在执行
合并
之前,我们可能需要根据
NA
的出现情况展开行。基于非NA元素创建数字索引(或使用
zoo
中的
NA.locf0
),
split
数据行序列(或获取'v1',v2'的
,并获取频率的
最大值
),通过基于“l1”填充NA行来展开行,然后对行执行
合并
。使用非NA元素(
NA.locf0
)填充行名后,通过
replace
将部分元素替换为NA来更改输出的行名

library(zoo)
v1 <- cumsum(!is.na(row.names(data1)))
v2 <- cumsum(!is.na(row.names(data2)))

lst1 <- split(seq_len(nrow(data1)), v1)
lst2 <- split(seq_len(nrow(data2)), v2)

l1 <- pmax(lengths(lst1), lengths(lst2))

dat1n <- do.call(rbind,  Map(function(x, y) data1[`length<-`(x, y), ], lst1, l1))
dat2n <- do.call(rbind,  Map(function(x, y) data2[`length<-`(x, y), ], lst2, l1))
row.names(dat1n) <- na.locf0(row.names(dat1n))
row.names(dat2n) <- na.locf0(row.names(dat2n))
out <-  merge(dat1n, dat2n, by = 'row.names', all = TRUE)

out1 <- as.matrix(out[-1])
row.names(out1) <- replace(out[,1], grepl("\\.\\d+$", out[,1]), NA)


out1
#      A.x     B.x C.x   D.x  E.x F.x A.y    B.y C.y   D.y   E.y  F.y
#alpha "Jenna" "1" "50"  "60" "7" "1" "Lena" "1" "23"  "77"  "7"  "1"
#<NA>  NA      NA  "67"  "99" NA  NA  NA     NA  "67"  "103" NA   NA 
#<NA>  NA      NA  "55"  NA   NA  NA  NA     NA  "55"  NA    NA   NA 
#<NA>  NA      NA  "45"  NA   NA  NA  NA     NA  NA    NA    NA   NA 
#beta  "Jenna" "1" "333" "89" "8" "1" NA     NA  NA    NA    NA   NA 
#<NA>  NA      NA  "755" "74" NA  NA  NA     NA  NA    NA    NA   NA 
#<NA>  NA      NA  "433" NA   NA  NA  NA     NA  NA    NA    NA   NA 
#<NA>  NA      NA  "300" NA   NA  NA  NA     NA  NA    NA    NA   NA 
#deta  NA      NA  NA    NA   NA  NA  "Lena" "1" "599" "9"   "76" "1"
#<NA>  NA      NA  NA    NA   NA  NA  NA     NA  "763" "88"  NA   NA 
#<NA>  NA      NA  NA    NA   NA  NA  NA     NA  "1"   NA    NA   NA 
#<NA>  NA      NA  NA    NA   NA  NA  NA     NA  "3"   NA    NA   NA 
图书馆(动物园)

v1您是否需要
merge(data1、data2、by='row.names',all=TRUE)
不幸的是,这根本不起作用伟大的答案!但是,当我应用于我的数据时(有10多个类似于这些给定示例的dfs),一些行名的前面有字母
“X”
。对于exmaple,
“ABC”
变为
“XABC”
。此外,某些行名不能转换正确的符号。例如,
“beta-[>0]”
变成了
“beta…0”。
。行名称也未排序:(@johnyton
merge
返回data.frame,data.frame不支持重复的列名或行名。这就是我在最后一步中更改为
as.matrix
的原因。哦!这就是
X
的来源。我想我知道如何修复它。谢谢!但是,我如何按行名对数据排序?因为它们必须是sort作为一个区块(如alpha作为区块,beta作为另一个区块…等等)@JohnnyTon我会使用'out'中的'Row.names'列进行排序,即,
out1[order(sub(“\\\.\\d+$”,“”,out$Row.names)),]
library(zoo)
v1 <- cumsum(!is.na(row.names(data1)))
v2 <- cumsum(!is.na(row.names(data2)))

lst1 <- split(seq_len(nrow(data1)), v1)
lst2 <- split(seq_len(nrow(data2)), v2)

l1 <- pmax(lengths(lst1), lengths(lst2))

dat1n <- do.call(rbind,  Map(function(x, y) data1[`length<-`(x, y), ], lst1, l1))
dat2n <- do.call(rbind,  Map(function(x, y) data2[`length<-`(x, y), ], lst2, l1))
row.names(dat1n) <- na.locf0(row.names(dat1n))
row.names(dat2n) <- na.locf0(row.names(dat2n))
out <-  merge(dat1n, dat2n, by = 'row.names', all = TRUE)

out1 <- as.matrix(out[-1])
row.names(out1) <- replace(out[,1], grepl("\\.\\d+$", out[,1]), NA)


out1
#      A.x     B.x C.x   D.x  E.x F.x A.y    B.y C.y   D.y   E.y  F.y
#alpha "Jenna" "1" "50"  "60" "7" "1" "Lena" "1" "23"  "77"  "7"  "1"
#<NA>  NA      NA  "67"  "99" NA  NA  NA     NA  "67"  "103" NA   NA 
#<NA>  NA      NA  "55"  NA   NA  NA  NA     NA  "55"  NA    NA   NA 
#<NA>  NA      NA  "45"  NA   NA  NA  NA     NA  NA    NA    NA   NA 
#beta  "Jenna" "1" "333" "89" "8" "1" NA     NA  NA    NA    NA   NA 
#<NA>  NA      NA  "755" "74" NA  NA  NA     NA  NA    NA    NA   NA 
#<NA>  NA      NA  "433" NA   NA  NA  NA     NA  NA    NA    NA   NA 
#<NA>  NA      NA  "300" NA   NA  NA  NA     NA  NA    NA    NA   NA 
#deta  NA      NA  NA    NA   NA  NA  "Lena" "1" "599" "9"   "76" "1"
#<NA>  NA      NA  NA    NA   NA  NA  NA     NA  "763" "88"  NA   NA 
#<NA>  NA      NA  NA    NA   NA  NA  NA     NA  "1"   NA    NA   NA 
#<NA>  NA      NA  NA    NA   NA  NA  NA     NA  "3"   NA    NA   NA