【问题标题】:Calculating item pair occurrences计算项目对出现次数
【发布时间】:2019-07-10 16:35:36
【问题描述】:

我有代表客户是否购买了某些商品的数据框。 df 如下所示:

P1  P2  P3  P4  P5
1   2   0   0   0
1   1   0   0   0
0   0   0   3   0 
1   0   0   1   0
1   0   5   1   0
1   1   0   0   0

我正在尝试创建有多少家庭购买了表中每个项目对的事件。结果的快照如下:

P1  P2  3
P1  P3  1
P1  P4  2
---------

作为第一步,我将数据转换为二进制格式 - 如果商品已购买。但是,我正在努力将其转换为项目对组的功能。

---我希望使用这些数据创建一个网络图,所以也许创建一个矩阵也有用

【问题讨论】:

  • 如果您的数据大小是一个问题,那么您可能会考虑下次在您的问题中提及这一点。由于您的粗鲁评论,我删除了我的答案,但是,为了回答您的问题,是的如果您按照嵌入式说明将其包装,我的解决方案(在您喜欢的任何答案前半小时出现)可以有效扩展一个函数。见?apply
  • 抱歉,这不是我的本意,不过谢谢您的回答
  • 另见this general QAas.data.frame(as.table(crossprod(as.matrix(d) > 0)))

标签: r dplyr


【解决方案1】:

调用你的数据d:

d = structure(list(P1 = c(1L, 1L, 0L, 1L, 1L, 1L), P2 = c(2L, 1L, 
0L, 0L, 0L, 1L), P3 = c(0L, 0L, 0L, 0L, 5L, 0L), P4 = c(0L, 0L, 
3L, 1L, 1L, 0L), P5 = c(0L, 0L, 0L, 0L, 0L, 0L)), .Names = c("P1", 
"P2", "P3", "P4", "P5"), class = "data.frame", row.names = c(NA, 
-6L))

我们可以使用combn:

pairs = combn(x = names(d), m = 2)
counts = combn(x = names(d), m = 2, FUN = function(x) sum(d[[x[1]]] > 0 & d[[x[2]]] > 0))

cbind.data.frame(t(pairs), counts)
#     1  2 counts
# 1  P1 P2      3
# 2  P1 P3      1
# 3  P1 P4      2
# 4  P1 P5      0
# 5  P2 P3      0
# 6  P2 P4      0
# 7  P2 P5      0
# 8  P3 P4      1
# 9  P3 P5      0
# 10 P4 P5      0

【讨论】:

    【解决方案2】:

    首先进行列名的所有成对组合:

      res <- as.data.frame( t( combn(names(dat),2)))
    

    然后对销售的两列中的存在进行逐行求和:

        res$counts <- apply(res, 1, function(rw)  sum( 
                                       pmin( as.logical(dat[ ,rw[1] ]), #rw[1] is col name 
                                             as.logical(dat[ , rw[2] ]) # 2nd col name
                            )               )        )
    
    > res
       V1 V2 counts
    1  P1 P2      3
    2  P1 P3      1
    3  P1 P4      2
    4  P1 P5      0
    5  P2 P3      0
    6  P2 P4      0
    7  P2 P5      0
    8  P3 P4      1
    9  P3 P5      0
    10 P4 P5      0
    

    【讨论】:

      【解决方案3】:

      您可以使用combn() 来构建这个:

      as.data.frame(t(combn(names(df),2, function(x) list(x[1], x[2], sum((df[,x[1]]*df[,x[2]])!=0)))))
         V1 V2 V3
      1  P1 P2  3
      2  P1 P3  1
      3  P1 P4  2
      4  P1 P5  0
      5  P2 P3  0
      6  P2 P4  0
      7  P2 P5  0
      8  P3 P4  1
      9  P3 P5  0
      10 P4 P5  0
      

      【讨论】:

      • 不错。你也可以as.data.frame(t(combn(df, 2, function(x) c(names(x), sum(x[1] * x[2] != 0)))))
      猜你喜欢
      • 2011-07-02
      • 2011-02-08
      • 1970-01-01
      • 2014-03-18
      • 2014-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-27
      相关资源
      最近更新 更多