【问题标题】:Iterate over unique combination of groups in a data frame迭代数据框中组的唯一组合
【发布时间】:2012-07-24 10:03:52
【问题描述】:

我在一个数据框中总结了 3 个不同的组。数据框如下所示:

d <- data.frame(v1 = c("A","A","A","B","B","B","C","C","C"), 

                v2 = c(1:9), stringsAsFactors = FALSE)

我想要的是将 A 的值与 B 的值进行比较。还将 A 的值与 B 的值进行比较,最后将 B 的值与 C 的值进行比较

我构造了 2 个 for 循环来迭代 v1 以提取要比较的组。但是,for 循环给了我所有可能的组合,例如:

A 与 A

A 与 B

A 与 C

B 与 A

B 与 B

B 与 C

C vs. A 等等...

这是我的 for 循环:

for(i in unique(d$v1)) {

    for(j in unique(d$v1)) {

        cat("i = ", i, "j = ", j, "\n")

        group1 <- d[which(d$v1 == i), ]

            group2 <- d[which(d$v1 == j), ]

        print(group1)
        print(group2)

        cat("---------------------\n\n")

    }
}

我怎样才能设法只迭代数据框d,以便在第一次迭代中 group1 包含 A 的值,group2 包含 B 的值。在第二次迭代中 group1 包含 A 和 group2 的值C。作为最后的比较,group1 包含 B 的值,group2 包含 C 的值。

不知何故,我完全被这个问题所困扰,并希望在这里找到答案。

干杯!

【问题讨论】:

  • 你想进行什么样的比较?
  • 好吧,我的原始数据框不是只有 v2,而是最多有 10 列。所以基本上 group1 是 d 的子数据框,有 11 列(c1=v1 和 c2:11 = 附加信息),用于 v1 == A。因此,group2 是相同的子集,但具有 v1 == B 的值。我希望这是有道理的......

标签: r iteration unique dataframe combinations


【解决方案1】:

也许这样的东西对你有用。再做一些工作,输出也可以“整理”一点。

我们将使用combn 找出组合,并使用lapply 根据组合对我们的数据进行子集化:

temp = combn(unique(d$v1), 2)
temp
#     [,1] [,2] [,3]
# [1,] "A"  "A"  "B" 
# [2,] "B"  "C"  "C" 
lapply(1:ncol(temp), function(x) cbind(d[d$v1 == temp[1, x], ],
                                       d[d$v1 == temp[2, x], ]))
# [[1]]
#   v1 v2 v1 v2
# 1  A  1  B  4
# 2  A  2  B  5
# 3  A  3  B  6
# 
# [[2]]
#   v1 v2 v1 v2
# 1  A  1  C  7
# 2  A  2  C  8
# 3  A  3  C  9
# 
# [[3]]
#   v1 v2 v1 v2
# 4  B  4  C  7
# 5  B  5  C  8
# 6  B  6  C  9

【讨论】:

  • 当然,您也可能更喜欢在function(x)... 之后使用rbindlist 而不是cbind
  • 这样做的好方法。多谢。这就是我一直在寻找的方式!
【解决方案2】:

我个人喜欢 mrdwab 的优雅回答,但如果你仍然想按照自己的方式使用循环,我会用这个来修复它(考虑到这会弄乱你的代码,最好保持整洁: )

u <- unique(d$v1)
for (i in 1:length(u)) {
    if (i < length(u)) {
        for (j in u[(i+1):length(u)]) {
            group1 <- d[which(d$v1 == u[i]), ]
            group2 <- d[which(d$v1 == j), ]
            cat("i = ", u[i], "j = ", j, "\n")
            print(group1)
            print(group2)
            cat("---------------------\n\n")
        }
    }
}

结果如下:

i =  A j =  B 
  v1 v2
1  A  1
2  A  2
3  A  3
  v1 v2
4  B  4
5  B  5
6  B  6
---------------------

i =  A j =  C 
  v1 v2
1  A  1
2  A  2
3  A  3
  v1 v2
7  C  7
8  C  8
9  C  9
---------------------

i =  B j =  C 
  v1 v2
4  B  4
5  B  5
6  B  6
  v1 v2
7  C  7
8  C  8
9  C  9
---------------------

【讨论】:

  • 排序良好 :) 但是,正如您所说,我认为 mrdwab 的解决方案是一种更好的方法 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 2019-01-13
  • 2017-01-04
相关资源
最近更新 更多