独特组合频率

6

我有一个包含10列的数据集。第一列是唯一标识符。另外9列是相关属性,假设它们都是整数。如果需要,可以将数据轻松地转换为键值对。

例如:

id|attr1|attr2|attr3|...
a |  2  |  5  |  7  |...
b |  3  |  1  |null |...
c |  2  |null |null |...
d |  1  |  2  |  5  |...
e |  2  |  1  |  3  |...

我主要寻找长度至少为一对的最频繁组合。因此,我的输出将会是:
unq   | frequency
1,2   | 2
1,3   | 2
1,5   | 1
2,3   | 1
2,5   | 2
2,7   | 1
1,2,3 | 1
1,2,5 | 1
2,5,7 | 1

(我手动完成了这个过程——希望没有错误)- 配对的顺序并不重要。2,5,7 = 5,2,7 = 7,5,2等等。 有什么想法吗?我可以使用不同的工具。我可以访问R,Excel,SQL Server,MySQL等等。 Excel是首选但不是必需的!

有多少属性,一个属性可以取哪些值?一个天真的算法可能无法扩展,我不知道是否存在可行的算法(但我不是专家)。 - frankc
你能解释一下你是如何从数据集得出答案的吗?我很难理解“任意长度的最常见组合,至少有一对”的含义。 - Richie Cotton
得到了更好的信息。它可以有1到9个属性。@Richie - 基本上对于D行 - 这里是该行的所有唯一组合(以分号分隔): 1 2 5 1,2 1,5 2,5 1,2,5 所以,唯一符合“至少一对”的是 1,2 1,5 2,5 1,2,5 这有帮助吗?如果没有,请随时再问。我想在我的回答中清楚明白。 - elgabito
2个回答

6

以下是 R 语言的解决方案:

重新创建数据:

x <- data.frame(
    id = letters[1:5],
    attr1 = c(2,3,2,1,2),
    attr2 = c(5,1,NA,2,1),
    attr3 = c(7,NA,NA,5,3))
x

  id attr1 attr2 attr3
1  a     2     5     7
2  b     3     1    NA
3  c     2    NA    NA
4  d     1     2     5
5  e     2     1     3

创建一个函数来列出所有的组合。
make_combinations <- function(data, size){
  t1 <- apply(data[, -1], 1, function(data)unname(sort(data)))
  t2 <- lapply(t1, function(xt){if(length(xt)>=size){combn(xt, size)}})
  t3 <- sapply(t2[!is.na(t2)], 
      function(chunk){if(!is.null(chunk))apply(chunk, 2, function(x)paste(x, collapse=","))})
  t4 <- unlist(t3)
  t4
}

创建第二个函数来计算组合数。
count_combinations <- function(data, nn=2:3){
  tmp <- unlist(lapply(nn, function(n)make_combinations(data, n)))
  sort(table(tmp), decreasing=TRUE)
}  

结果如下:
count_combinations(x, 2:3)


  1,2   1,3   2,5 1,2,3 1,2,5   1,5   2,3 2,5,7   2,7   5,7 
    2     2     2     1     1     1     1     1     1     1 

我遇到了 Error in apply(x[, -1], 1, function(data) unname(sort(data))) : object 'x' not found 的错误信息,因为我非常新手,所以可能是我做错了什么? - elgabito
1
是的,非常抱歉。但现在已经是周五晚上了。我应该完成真正的工作,并且需要花些时间陪伴另一半。如果要进行逆向工程,请问能否在代码中包含打印语句以打印t1,t2,t3和t4?这应该可以相当清楚地说明发生了什么。 - Andrie
1
兄弟,你太棒了 - 完全奏效了。第一次使用R,我印象深刻。如果你或其他人能告诉我如何将此输出转换为两列表格,那就太好了,但这太棒了! - elgabito
combs <- count_combinations(x, 2:3),然后使用data.frame(Combs = names(combs), Count = combs)可以得到两列数据。 - Gavin Simpson
1
以防其他人通过搜索进入,我跳过了上面的第一部分,创建了两个函数(只需复制/粘贴),导入我的csv rawsku <- read.table("rawsku.csv",header=T,sep=","),确保它看起来正确 names(rawsku); head(rawsku) 然后运行 rawsku_results <- count_combinations(rawsku,2:9) 2:9 寻找2到9之间的分组,然后将其写入csv:write.csv(rawsku_results,file="rawsku_results.csv") - elgabito
显示剩余2条评论

2

这是您的数据,没有id列。

dfr <- data.frame(
  attr1 = c(2,3,2,1,2), 
  attr2 = c(5,1,NA,2,1), 
  attr3 = c(7,NA,NA,5,3)
)

这将检索出所有的组合,但输出形式需要一些导航才能看懂。
lapply(
  seq_len(nrow(dfr)),              #loop over rows
  function(row) 
  {
    lapply(
      seq_along(dfr)[-1],          #loop over lengths of combination, -1 is to ignore singletons
      function(m) 
      {
        combn(dfr[row, ], m)
      }
    )
  }
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接