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

时间:2016-07-12 15:46:16

标签: python r vba python-3.x openrefine

我有两列中的数据,如下所示

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

我希望根据相同的ID(例如

)将所有可能组合中的“值”列的数据结合起来
(a,c)
(a,h)
(c,h)
(f,a)

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

3 个答案:

答案 0 :(得分:2)

使用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

答案 1 :(得分:2)

要使用基数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将data.frame由Id拆分为两个data.frames的列表。然后sapply被提供此列表和combn函数以查找这些data.frames中的成对组合。每个data.frame(这是一个矩阵)的结果将使用t转换为适合您所需的结构。最后,这个矩阵列表被输入do.call,使用rbind返回最终矩阵。

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

答案 2 :(得分:2)

另一种方式(可能稍快一点,因为它利用了您正在寻找所有的事实,并避免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')