【问题标题】:R For a list Generate all combinations of factor, all combinations of merges, and combineR 对于一个列表 生成因子的所有组合,所有合并的组合,并组合
【发布时间】:2015-10-15 19:32:52
【问题描述】:

所以我正在处理癌症分期数据。假设有一个这种类型的数据集。它是一个数据框。

   cancertype     stage
TCGA-67-6215-01     1
TCGA-67-6216-01     1
TCGA-67-6217-01     2
TCGA-69-7760-01     2
TCGA-69-7761-01     1
TCGA-69-7763-01     1
TCGA-69-7764-01     1
TCGA-69-7765-01     4
TCGA-69-7980-01     1
TCGA-71-6725-01     1
TCGA-73-4658-01     1
TCGA-73-4659-01     3
TCGA-73-4662-01     1
TCGA-73-4675-01     3

所以我想要的是一个列表,其中每个元素都是一个数据框。这里有 4 个级别用于 4 个可能的癌症阶段。每个级别的 2 个级别、3 个级别等的组合都应该有数据框,直到数据中的级别数。但也是每个合并级别组合的数据框。我的意思是

list(
dataframe of stage1 and 2
dataframe of stage1 and 3
dataframe of stage 1 and 4
dataframe of stage 2 and 3
...etc
dataframe of stage 1,2 and 3
dataframe of stage 2,3 and 4
...
dataframe of stage 1,2 and 3,4
dataframe of stage 1,3 and 2,4
dataframe of stage 1,2,3 and 4
dataframe of stage 1,2,4 and 3
.. etc etc I think this should give you the idea.
)

在这里,当我说第 1、2、4 阶段时,我的意思是它们都已合并到一个级别。

我基本上是在尝试对 t 检验进行所有可能的比较,因此我正在设置进行比较所需的样本。做所有可能的组合并合并组合会很好。

到目前为止,我能够结合未合并比较的所有元素 这是 11 。即2段6连击、3段4连击、4段1连击

stage # dataframe of stage data as factors
stage_split <-split(stage,stage[,1])
allcombos<- c(combn(stage_split,2,simplify=F), combn(stage_split,3,simplify=F), combn(stage_split,4,simplify=F))
allcombos_cmbnd<- lapply(allcombos, function(x) Reduce(rbind,x))

如何从所有可能的合并排列中生成额外的数据帧,然后附加到此列表中?也许从第一个数据帧有一种优雅的方式来实现这一点。一种方法是遍历这个 11 的列表并从 3 的组合开始生成合并?我可以暴力破解它,但我希望有一种优雅的方式来执行这个可以扩大规模。到目前为止,我没有找到任何解释如何生成数据中的所有级别组合以及所有级别的合并组合。

感谢您的帮助

【问题讨论】:

  • 你能给我们展示一些组合的例子吗? @user227710 的评论将,例如 expand.grid(list(1:3,1:4))

标签: r merge split combinations reduce


【解决方案1】:

当您将阶段分组在一起时,您正在对大小为 3 或 4 的集合进行分区。有一个包 partitions 使用 setparts 实现集合分区。在这里,我专注于合并部分,因为听起来您已经弄清楚了非合并分组。

 ## For unmerged, get groupings with something like this
combos <- unlist(lapply(2:4, function(x) combn(unique(dat$stage), x, simplify=F)), rec=F)

## For merged groupings, use set partitioning
library(partitions)
dats <- unlist(sapply(3:4, function(p) {
    parts <- setparts(p)  # set partitions of size p
    lst <- lapply(split(parts, col(parts)), function(idx) {
        if (p==3) {       # with sets of 3, need to exclude one of the stages
            subLst <- lapply(1:4, function(exclude) {
                tmp <- dat$stage
                tmp[dat$stage==exclude] <- NA
                ids <- seq(4)[-exclude]
                for (i in 1:3) tmp[dat$stage==ids[i]] <- idx[i]
                data.frame(dat$cancertype, stage=tmp)
            })
            names(subLst) <- paste(1:4)
            subLst
        } else {          # sets of 4, no need to exclude
            tmp <- dat$stage
            for (i in 1:length(idx)) tmp[dat$stage==i] <- idx[i]
            data.frame(dat$cancertype, stage=tmp)
        }
    })
    names(lst) <- lapply(split(parts, col(parts)), paste, collapse=".")
    lst
}), rec=F)

dats 现在是data.frames 的列表,其中stages 按设置的分区分组。在对大小为 3 的集合进行分区时,必须删除其中一个阶段。因此,dats 中的这些条目显示为长度为 4 的列表,每个元素对应于从考虑中删除一个阶段(列表是有序的,因此第一个组件删除阶段 1,第二个组件删除阶段 2,等等)。让我们看一个或 3 大小的分区,

dats[4]
$`2.1.1`
# $`2.1.1`$`1`
#     dat.cancertype stage
# 1  TCGA-67-6215-01    NA
# 2  TCGA-67-6216-01    NA
# 3  TCGA-67-6217-01     2
# 4  TCGA-69-7760-01     2
# 5  TCGA-69-7761-01    NA
# 6  TCGA-69-7763-01    NA
# 7  TCGA-69-7764-01    NA
# 8  TCGA-69-7765-01     1
# 9  TCGA-69-7980-01    NA
# 10 TCGA-71-6725-01    NA
# 11 TCGA-73-4658-01    NA
# 12 TCGA-73-4659-01     1
# 13 TCGA-73-4662-01    NA
# 14 TCGA-73-4675-01     1
# 
# $`2.1.1`$`2`
#     dat.cancertype stage
# 1  TCGA-67-6215-01     2
# 2  TCGA-67-6216-01     2
# 3  TCGA-67-6217-01    NA
# 4  TCGA-69-7760-01    NA
# 5  TCGA-69-7761-01     2
# 6  TCGA-69-7763-01     2
# 7  TCGA-69-7764-01     2
# 8  TCGA-69-7765-01     1
# 9  TCGA-69-7980-01     2
# 10 TCGA-71-6725-01     2
# 11 TCGA-73-4658-01     2
# 12 TCGA-73-4659-01     1
# 13 TCGA-73-4662-01     2
# 14 TCGA-73-4675-01     1

这里的命名约定是group1.group2.group3$excludedGroup,相同的数字表示组已合并。所以,2.1.1$1 表示第一组已被排除($1,实际上只是转换为NA),而在剩余的数据中,第 2 组和第 3 组已合并。这有点令人困惑,可能需要更好的命名方案。例如,$2.1.1$1 表示“阶段 1 被排除 (NA),阶段 3 和阶段 4 已合并”。因此,我可以使用dats[['2.1.1']][['1']] 访问该数据。此列表中还有两个未显示的 data.frame(不包括阶段 3 和 4)。

现在,set-4 分区更加简单,因为没有排除项。例如,

dats[19]
# $`2.3.1.1`
#     dat.cancertype stage
# 1  TCGA-67-6215-01     2
# 2  TCGA-67-6216-01     2
# 3  TCGA-67-6217-01     3
# 4  TCGA-69-7760-01     3
# 5  TCGA-69-7761-01     2
# 6  TCGA-69-7763-01     2
# 7  TCGA-69-7764-01     2
# 8  TCGA-69-7765-01     1
# 9  TCGA-69-7980-01     2
# 10 TCGA-71-6725-01     2
# 11 TCGA-73-4658-01     2
# 12 TCGA-73-4659-01     1
# 13 TCGA-73-4662-01     2
# 14 TCGA-73-4675-01     1

这里的命名是“Group1.Group2.Group3.Group4”。例如,在此分组阶段 3 和 4 已合并(均 == 1)。

这里有冗余,您可以使用分区集或大小为 3 的排除集或大小为 4 的分区集,并对每个 data.frame 进行多重比较。例如,在上面显示的数据集中,可以使用dats[['2.3.1.1']] 或同时使用dats[['2.1.1']][['1']]dats[['2.1.1']][['2']] 来完成等效测试。

为了简化事情,您可以只存储索引,或者只在循环中进行计算,而不是将所有这些 data.frames 存储在一个列表中。

【讨论】:

  • 非常感谢!令人惊讶的是你这么快就想出了什么。对我来说,以有效的方式将其推广到任何规模是一个有趣的问题。它似乎是集合和每个子集的 bell #s 的总和。我仍然觉得必须有一种更优雅的方式来解决这个问题。我不知道它是什么!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多