【问题标题】:R merge data frames matching row- _and_ colnamesR合并匹配行的数据帧-_and_ colnames
【发布时间】:2013-10-18 12:13:16
【问题描述】:

我正在寻找一种简单的方法来组合两个数据帧,方法是将较小的数据帧插入较大的数据帧,如下所示:

 x.1: x.2:
         1.1 1.2 2.3 3.4 1.2 2.3
    a.b w z d.e u
    b.c x a.b v
    d.e y

想要的结果:

 x.f:
         1.1 1.2 2.3 3.4
    a.b w v z
    公元前x
    d.e y u

很多问题只在 cols 之后进行合并,但我想根据 cols 行的名称进行合并,但不明白。名称中的点是一个修复方案。如果有人提出建议会很高兴,因为我尝试合并、加入等没有成功。我认为的一种解决方案是手动方式,通过循环遍历较小的框架,每次查找值并保存行/列,然后插入更大的框架。或重组我的数据框。但一定有更简单的方法吗?

提前谢谢, 罗宾

这是快速试用的代码:

i<-c("w", "", "y")
j<-c("", "x", "")
k<-c("","","")
l<-c("z","","")
x.1 <- data.frame(i,j,k,l, row.names=c("a.b","b.c","d.e"))
colnames(x.1)<-c("1.1","1.2","2.3","3.4")
m<-c("u", "")
n<-c("", "v")
x.2 <- data.frame(m,n, row.names=c("d.e","a.b"))
colnames(x.2)<-c("1.2","2.3")

【问题讨论】:

  • 如果both data.frames 的某个行/列组合有值怎么办,或者这是不可能的情况?
  • 你的意思是,当一个值将被插入到一个已经持有一个值的位置时,如何处理这种情况?好吧,这应该不是场景,但这可能是由于输入数据时出现错误。我必须小心,看看你的解决方案会发生什么。顺便说一句,它正在工作,非常感谢这个和你的替代方案!

标签: r join insert merge


【解决方案1】:

这是一种方法:

library(reshape2)
mx1 <- melt(cbind(id = rownames(x.1), x.1), id.vars="id")
mx2 <- melt(cbind(id = rownames(x.2), x.2), id.vars="id")
x12 <- rbind(mx1, mx2)
out <- dcast(x12[!x12$value == "", ], id ~ variable)
out[is.na(out)] <- ""
out
#    id 1.1 1.2 2.3 3.4
# 1 a.b   w       v   z
# 2 b.c       x        
# 3 d.e   y   u       

首先将每个数据集变成“长”数据集(最简单的是使用“reshape2”中的melt),然后将其转换回“宽”数据集(再次使用“reshape2”中的dcast)。

上述步骤并非全部必需,但我已将它们包括在内以尽可能接近您所需的输出,以便您决定保留/删除哪些步骤。


其实,如果你问我,我会停留在“x12”阶段。从长远来看,“长”数据可能更便于操作和使用(没有双关语)。


更新

您可能还想考虑“datamerge”包,它实际上包含两个函数:clean.factors()version.mergeclean.factors 函数将负责在合并之前将空白转换为 NA。我保留了verbose = TRUE,因此您可以看到它确实为您提供了一些有关如何执行合并的详细信息,包括在此过程中是否必须更改任何值。

out <- Reduce(function(x, y) version.merge(x, y, add.values = TRUE, verbose = TRUE), 
              lapply(list(x.1, x.2), clean.factors, verbose = FALSE))
# Rows:  3 from `x` #1
#        0 from `y` #2
# 
# Columns:
# 1.1  Origin: `x` #1
# 1.2  Origin: `x` #1
#      Imputed 1 values from `y` #2
# 2.3  Origin: `x` #1
#      Imputed 1 values from `y` #2
#      Class missmatch: numeric vs. character
#      Converted to character
# 3.4  Origin: `x` #1

out
#      1.1  1.2  2.3  3.4
# a.b    w <NA>    v    z
# b.c <NA>    x <NA> <NA>
# d.e    y    u <NA> <NA>

当然,如果您想再次将NAs 替换为空白,您只需使用out[is.na(out)] &lt;- ""

【讨论】:

  • +1 我很想看到 data.table 的语法。我期待着像x.1[ mergemagic( x.2 ) ]这样的花哨和古怪的东西:-)
  • @SimonO101,好吧,既然 Arun 基本上一直在为 data.table 进行融合和转换,那么语法很有可能不会有太大的不同。
【解决方案2】:
flatx.2 <- which(!x.2 =="", arr.ind=TRUE)
flatx.2[] <- cbind( rownames(x.2)[flatx.2[,'row']], 
                    colnames(x.2)[flatx.2[,'col']])
flatx.2  
# contains row and column names in same positions as the non-blank x.2 values
#---------
    row   col  
d.e "d.e" "1.2"
a.b "a.b" "2.3"
#--------------
x.1[ cbind(  match(flatx.2[,1], rownames(x.1)),          #identify numeric row
            match(flatx.2[,2], colnames(x.1))) ] <-      #identify numeric col
                 x.2[which(!x.2 =="", arr.ind=TRUE)]    # the non-blank values
 x.1
#-------------
    1.1 1.2 2.3 3.4
a.b   w       v   z
b.c       x        
d.e   y   u        

我碰巧认为仅使用基本索引操作就相当不错(并且应该相当有效并且适用于具有所需技能的人的 data.table 结构),所以希望得到一点掌声。我以为我可以只使用 LHS 上的字符值位置矩阵,但我的尝试出错了。 ?"[" 页面似乎在说它应该可以工作,所以如果我犯了语法错误,也许可以简化一下。

【讨论】:

  • 我也觉得这很酷。特别是因为我第一次通过安装 reshape2 遇到了困难和错误......但它最终通过编译包源进行安装。到目前为止,也会尝试你的代码,谢谢!
猜你喜欢
  • 2018-03-18
  • 1970-01-01
  • 2017-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
相关资源
最近更新 更多