所有组合按组取一个
All combinations picking one by group
给定一个组指标变量和组内的一些值:
group = rep(c(1,2), each = 3)
val = letters[1:6]
cbind(group, val)
group val
[1,] "1" "a"
[2,] "1" "b"
[3,] "1" "c"
[4,] "2" "d"
[5,] "2" "e"
[6,] "2" "f"
我正在寻找一个矩阵,它给我所有独特的组合,这些组合是将每个组中的 one 元素与每个组中的 one 元素组合而成的其他组。也就是说,每组只允许一个个元素在每个组合中是''active''。
所需的输出是一个矩阵,其中每一列代表一种可能的组合。结果矩阵的前四列可能如下所示:
[,1] [,2] [,3] [,4]
[1,] 1 0 0 1
[2,] 0 1 0 0
[3,] 0 0 1 0
[4,] 1 1 1 0
[5,] 0 0 0 1
[6,] 0 0 0 0
其中行对应于上面输入矩阵中给出的行。第一列告诉您 a
在组 1
中活跃,d
在组 2
中活跃。第二列告诉您 b
在组 1
中活跃,d
在组 2
中活跃。第三列告诉您 c
在 1
中有效,d
在 2
中有效,依此类推。因此,每列的总和将始终等于组数,因为每个组只允许一个元素处于活动状态。
我对如何以有组织的方式获得所需的输出矩阵感到有点困惑。我一直在考虑枚举所有可能的组合并限制为可行的组合(其中组内生成的向量元素的总和对于所有组来说恰好等于一个),但这可能会导致大数据集的内存问题,我不确定有没有更优雅高效的方法
编辑:解决方案应推广到任意数量的组和组内任意数量的元素 (>1)。
我认为这应该根据需要扩展:
group = rep(c(1,2), each = 3)
val = letters[1:6]
input = data.frame(group, val)
combos = do.call(expand.grid, split(input$val, input$group))
combo_matrix = matrix(0, nrow = nrow(input), ncol = nrow(combos))
for(i in 1:ncol(combos)) {
combo_matrix[cbind(match(combos[[i]], input$val), 1:ncol(combo_matrix))] = 1
}
combo_matrix
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
# [1,] 1 0 0 1 0 0 1 0 0
# [2,] 0 1 0 0 1 0 0 1 0
# [3,] 0 0 1 0 0 1 0 0 1
# [4,] 1 1 1 0 0 0 0 0 0
# [5,] 0 0 0 1 1 1 0 0 0
# [6,] 0 0 0 0 0 0 1 1 1
它假设 val
值在 input
数据框中不重复。
给定一个组指标变量和组内的一些值:
group = rep(c(1,2), each = 3)
val = letters[1:6]
cbind(group, val)
group val
[1,] "1" "a"
[2,] "1" "b"
[3,] "1" "c"
[4,] "2" "d"
[5,] "2" "e"
[6,] "2" "f"
我正在寻找一个矩阵,它给我所有独特的组合,这些组合是将每个组中的 one 元素与每个组中的 one 元素组合而成的其他组。也就是说,每组只允许一个个元素在每个组合中是''active''。
所需的输出是一个矩阵,其中每一列代表一种可能的组合。结果矩阵的前四列可能如下所示:
[,1] [,2] [,3] [,4]
[1,] 1 0 0 1
[2,] 0 1 0 0
[3,] 0 0 1 0
[4,] 1 1 1 0
[5,] 0 0 0 1
[6,] 0 0 0 0
其中行对应于上面输入矩阵中给出的行。第一列告诉您 a
在组 1
中活跃,d
在组 2
中活跃。第二列告诉您 b
在组 1
中活跃,d
在组 2
中活跃。第三列告诉您 c
在 1
中有效,d
在 2
中有效,依此类推。因此,每列的总和将始终等于组数,因为每个组只允许一个元素处于活动状态。
我对如何以有组织的方式获得所需的输出矩阵感到有点困惑。我一直在考虑枚举所有可能的组合并限制为可行的组合(其中组内生成的向量元素的总和对于所有组来说恰好等于一个),但这可能会导致大数据集的内存问题,我不确定有没有更优雅高效的方法
编辑:解决方案应推广到任意数量的组和组内任意数量的元素 (>1)。
我认为这应该根据需要扩展:
group = rep(c(1,2), each = 3)
val = letters[1:6]
input = data.frame(group, val)
combos = do.call(expand.grid, split(input$val, input$group))
combo_matrix = matrix(0, nrow = nrow(input), ncol = nrow(combos))
for(i in 1:ncol(combos)) {
combo_matrix[cbind(match(combos[[i]], input$val), 1:ncol(combo_matrix))] = 1
}
combo_matrix
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
# [1,] 1 0 0 1 0 0 1 0 0
# [2,] 0 1 0 0 1 0 0 1 0
# [3,] 0 0 1 0 0 1 0 0 1
# [4,] 1 1 1 0 0 0 0 0 0
# [5,] 0 0 0 1 1 1 0 0 0
# [6,] 0 0 0 0 0 0 1 1 1
它假设 val
值在 input
数据框中不重复。