子集中所有可能的组合,多列

Posted

技术标签:

【中文标题】子集中所有可能的组合,多列【英文标题】:all possible combinations within subset, multicolumn 【发布时间】:2014-08-01 08:55:25 【问题描述】:

寻找一些帮助来为 Excel 创建脚本以生成所有可能的数据组合。这是我拥有的和正在寻找的示例。 ID 是子集标识号,AID 是该子集中的参与者。

ID  AID
 1   30
 1   52
 1   10
 1   20
 2   10
 2   11
 2   50

需要:

ID  AID  AID1
 1   30   52
 1   30   10
 1   30   20
 1   52   10
 1   52   20
 1   10   20
 2   10   11
 2   10   50
 2   11   50

任何帮助将不胜感激。希望在 Excel 中执行此操作,但 R 也可以。谢谢!!

【问题讨论】:

AID1 到底是什么,即您要达到什么目的? 请阅读 Excel 中的交叉连接。您可以轻松地在网上找到代码或获得一些额外的插件。 【参考方案1】:

看起来您实际上并不拥有所有组合。您是否考虑过使用 SQL 来解决您的问题?您可以使用 R 中的 sqldf 包来执行此操作,并将数据与自身交叉连接。这给出了所有组合:

library(sqldf)

sqldf("select a.ID, a.AID, b.AID AID1
       FROM data a 
       JOIN data b ON a.ID = b.ID")

这给出了问题中显示的输出:

sqldf("select a.ID, a.AID, b.AID AID1
       FROM data a 
       JOIN data b ON a.ID = b.ID and a.rowid < b.rowid")

【讨论】:

谢谢大家。这个真的很好用。我确实把它放到了一个新的数据表中,因为我的控制台上的 obs 数量达到了 3500。总而言之,12K obs 现已完成。简单!再次感谢! 您能否为有帮助的答案投票并勾选正确的答案?谢谢 不幸的是,我的代表不够强大,无法投票。也就是说,这个建议对我来说效果最好。第二个代码是我使用的那个,因为我想最终成对使用。【参考方案2】:
dat <- read.table(text="
ID  AID
1   30
1   52
1   10
1   20
2   10
2   11
2   50",sep="",header=TRUE)


res <- do.call(rbind,lapply(split(dat, dat$ID), function(x)    setNames(data.frame(x$ID[1], t(combn(x$AID,2))),c("ID", paste0("AID",c("",1))))))
row.names(res) <- 1:nrow(res)

出现该错误的一种可能性是:

dat <- structure(list(ID = c(1L, 1L, 1L, 1L, 2L), AID = c(30L, 52L, 
10L, 20L, 1L)), .Names = c("ID", "AID"), class = "data.frame", row.names = c(NA, 
-5L))

lapply(split(dat,dat$ID),function(x) combn(x$AID,2))
#Error in combn(x$AID, 2) : n < m

res <- do.call(rbind, lapply(split(dat, dat$ID), function(x) 
if (length(x$AID) > 1) 
    setNames(data.frame(x$ID[1], t(combn(x$AID, 2))), c("ID", paste0("AID", c("", 
        1)))) else transform(x, AID1 = AID)
))

row.names(res) <- 1:nrow(res)

【讨论】:

我的不是文本,而是导入到 R 的 csv 文件。使用此方法时出现此错误:Combn(x$AID, 2) 中的错误:n 请使用 ?dput() 显示一个小示例数据(产生错误)【参考方案3】:

这里的方法有点类似于Guest,但是使用by按ID进行拆分。

z <- by(x$AID, x$ID, function(i) if(length(i)>1) combn(i,2) else NULL)
do.call(rbind, lapply(names(z), 
        function(i) if (is.null(z[[i]])) NULL else data.frame(ID=i, t(z[[i]])))
)
##   ID X1 X2
## 1  1 30 52
## 2  1 30 10
## 3  1 30 20
## 4  1 52 10
## 5  1 52 20
## 6  1 10 20
## 7  2 10 11
## 8  2 10 50
## 9  2 11 50

根据需要设置名称。

NULL 用于在传递给by 的函数中返回,以便可以在lapply 表达式中对其进行过滤。 rbind 忽略 NULL 输入。

【讨论】:

以上是关于子集中所有可能的组合,多列的主要内容,如果未能解决你的问题,请参考以下文章

在C中创建n个项目的k和m个组合的所有可能子集[重复]

一文搞懂全排列组合子集问题(建议收藏)

多列组合在猪中唯一

Excel:如何计算多列单元格的组合?

选择项目后将多列组合框的值设置为所有列?

77. 组合