以所有可能的组合耦合数据

Couple the data in all possible combinations

我在列中有两列数据,就像这样

Id  Value
1   a
2   f
1   c
1   h
2   a

并且我想根据相同的 ID 将 'Value' 列的数据组合成所有可能的组合,例如

(a,c)
(a,h)
(c,h)
(f,a)

是否有任何 R 或 Python 或 VBA 代码来完成此任务?

使用 R 你可以试试:

library(purrr)

df %>%
  split(.$Id) %>%
  map(~ t(combn(.$Value, 2)))

给出:

#$`1`
#     [,1] [,2]
#[1,] "a"  "c" 
#[2,] "a"  "h" 
#[3,] "c"  "h" 
#
#$`2`
#     [,1] [,2]
#[1,] f    a   
#Levels: a c f h

要return一个使用基数R的这些组合的字符矩阵,尝试

do.call(rbind, t(sapply(split(df, df$Id), function(i) t(combn(i$Value, 2)))))
     [,1] [,2]
[1,] "a"  "c" 
[2,] "a"  "h" 
[3,] "c"  "h" 
[4,] "f"  "a"

每一行都是所需的组合。

为了稍微分解一下,split 按 Id 将 data.frame 拆分为两个 data.frame 的列表。然后 sapply 被提供给这个列表和 combn 函数来找到这些 data.frame 中的成对组合。使用 t 转置每个 data.frame(矩阵)的结果以适应您想要的结构。最后,这个矩阵列表被馈送到 do.call,它使用 rbind 到 return 最终矩阵。

注意:假设值列是字符(不是讨厌的因子变量类型)。这在 read. 系列函数中很容易实现,例如 read.csvread.table 通过将 as.is=TRUE 参数添加到您的读取函数(或更长的 stringsAsFactors=FALSE) .如果变量已经是一个因素,您可以将 i$Value 语句包装在 as.character 的末尾附近: as.character(i$Value) 它将根据需要 运行。

只是另一种方式(可能稍微快一些,因为它利用了您正在寻找所有 并避免 combnt 的事实) :

require(data.table)
dt[, .( c1 = rep(Value, (.N:1)-1L), c2 = rep(Value, (1:.N)-1L) ), by=Id]
#    Id c1 c2
# 1:  1  a  c
# 2:  1  a  h
# 3:  1  c  h
# 4:  2  f  a

.N 包含每个组的观察数。


其中 dt 是:

dt = fread('Id  Value
1   a
2   f
1   c
1   h
2   a')