【问题标题】:Merge all possible combinations of multiple data frames合并多个数据帧的所有可能组合
【发布时间】:2016-05-24 11:43:36
【问题描述】:

我想按列合并这三个数据框的所有可能对组合(即九个组合)

frame1 = data.frame(a=c(1,2,3), b=c(1,2,3), c=c(1,2,3))
frame2 = data.frame(a=c(2,1,3), b=c(2,1,3), c=c(2,1,3))
frame3 = data.frame(a=c(3,2,1), b=c(3,2,1), c=c(3,2,1))

其中每行包含相同的 3 行,但顺序不同,所以我还希望合并是两个文件中列 a 和 b 的值对的巧合。示例:

a b c
1 1 1 
2 2 2
3 3 3

+

a b c
2 2 2
1 1 1   
3 3 3

=

a.x b.x c.x a.y b.y c.y
1 1 1 1 1 1  
2 2 2 2 2 2
3 3 3 3 3 3

然后我想获得每个合并文件中存在的列 c.x 和 c.y 的每对值之间的绝对值差异,并将所有这些差异相加,从而获得“分数”(当然这将是零这个例子),我想将它添加到对应单元格中的空矩阵 ​​3x3 中(即 frame1 与 frame 2 的分数应该位于单元格 [2,1] 中,等等):

nframes = 3
frames = c(frame1,frame2,frame3)

matrix = matrix(, nrow = nframes, ncol = nframes)
matrix_scores = data.frame(matrix)

for (i in frames){
  for (j in frames)
   {
    x = merge(i, j, by=c("a","b"))
    score = sum(abs(x$c.x - x$c.y))
    matrix_scores[j,i] <- score
  }
}

但是,当我运行循环时,我收到以下消息:

Error in fix.by(by.x, x) : 'by' must specify uniquely valid columns

另外,我明白这条线

matrix_scores[j,i] <- score

也会给出错误,但我不知道如何表达我希望将分数存储在单元格 [1,1] 中,用于循环的第一次迭代(frame1 与 frame1)。

生成的矩阵应该是一个包含全零的 3x3 矩阵:

       f1 f2 f3
frame1 0 0 0
frame2 0 0 0
frame3 0 0 0

【问题讨论】:

  • 你的代码有几个地方有问题。您没有将数据框存储在列表中,而是使用了frames = c(frame1, frame2,..)。此处的连接函数不正确list(frame1, frame2,...) 可能会更好。在循环中,同一个数据框有时会与自身合并。
  • 改了之后,错误变成了Error in seq_len(nrows)[i] : invalid subscript type 'list'
  • 我没有说那是你的最终解决方案。我正在向您展示您的方法中的第一个错误。如果您想使用c(),那就去玩吧。

标签: r loops merge


【解决方案1】:

你可以这样做:

# Put all frames in a list
d <- list(frame1, frame2, frame3)
# get all merge-combinations
gr <- expand.grid(1:length(d), 1:length(d))

# function to merge and get the sum diff:
foo <- function(i, x, gr){
  tmp <- merge(x[[gr[i, 1]]], x[[gr[i, 2]]], by=c("a", "b"))
  sum(abs(tmp$c.x - tmp$c.y))
}

# result matrix
matrix(sapply(1:nrow(gr), foo, d, gr), length(d), length(d),  byrow = T)
      [,1] [,2] [,3]
[1,]    0    0    0
[2,]    0    0    0
[3,]    0    0    0

# The scores are set as followed:
matrix(apply(gr, 1, paste, collapse="_"), 3, 3,  byrow = T)
      [,1]  [,2]  [,3] 
[1,] "1_1" "2_1" "3_1"
[2,] "1_2" "2_2" "3_2"
[3,] "1_3" "2_3" "3_3"


# alternative using apply:

# function to merge and get the sum diff:
foo <- function(y, x){
  tmp <- merge(x[[ y[1] ]], x[[ y[2] ]], by=c("a", "b"))
  sum(abs(tmp$c.x - tmp$c.y))
}
# result matrix
matrix(apply(gr, 1, foo, d), length(d), length(d),  byrow = T)

【讨论】:

  • 谢谢 Jimbou,它看起来像我想要的,但在 gr &lt;- expand.grid(1:length(x), 1:3) 之后给我一个错误:Error in expand.grid(1:length(x), 1:3) : object 'x' not found
  • @Michael 我解决了这个问题。您必须将x 更改为d。另请参阅我包含了byrow 参数来按行构建矩阵。请考虑接受它作为有用的答案。
  • 是的,现在它可以工作了,我接受它,但请将其添加到函数中:sum(abs(tmp$r.2.x - tmp$r.2.y)),因为我想要绝对值。否则效果很好,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-09
  • 1970-01-01
相关资源
最近更新 更多