【问题标题】:Generate matrix of unique user-item cross-product combinations生成唯一用户-项目交叉产品组合的矩阵
【发布时间】:2015-09-14 08:29:13
【问题描述】:

我正在尝试在 R 中创建一个唯一用户的交叉产品矩阵。我在 SO 上搜索了它,但找不到我要找的东西。任何帮助表示赞赏。 我有一个大数据框(超过一百万)并显示了一个示例:

df <- data.frame(Products=c('Product a', 'Product b', 'Product a', 
                            'Product c', 'Product b', 'Product c'),
                 Users=c('user1', 'user1', 'user2', 'user1', 
                         'user2','user3'))

df 的输出是:

   Products Users
1 Product a user1
2 Product b user1
3 Product a user2
4 Product c user1
5 Product b user2
6 Product c user3

我想查看两个矩阵: 第一个将显示拥有任一产品(或)的唯一用户数 - 因此输出将类似于:

            Product a   Product b   Product c
Product a                 2            3
Product b     2                        3
Product c     3           3 

第二个矩阵将是拥有两种产品的唯一用户数(AND):

            Product a   Product b   Product c
Product a                 2            1
Product b     2                        1
Product c     1           1 

感谢任何帮助。

谢谢

更新:

这里更清楚:产品 a 由 User1 和 User2 使用。产品 b 由 User1 和 User2 使用,产品 c 由 User1 和 User3 使用。所以在第一个矩阵中,产品 a 和产品 b 将是 2,因为有 2 个唯一用户。同样,产品 a 和产品 c 将为 3。在第二个矩阵中,它们将是 2 和 1,因为我想要交集。 谢谢

【问题讨论】:

  • 预期输出中的数字是否代表示例中显示的值?对于第二种情况,可能是tbl &lt;- table(merge(df, df, by.x='Users', by.y='Users')[-1]); diag(tbl) &lt;- 0
  • @akrun 我同意你的看法......示例 df 输出似乎与所需的输出不一致。
  • @TimBiegeleisen 第一种情况不清楚。我得到了第二个的预期输出
  • 或者第二个输出可以是tcrossprod(table(df))*!diag(3)
  • @akrun 他们应该。这里更清楚:产品 a 由 User1 和 User2 使用。产品 b 由 User1 和 User2 使用,产品 c 由 User1 和 User3 使用。所以在第一个矩阵中,prod a 和 prod b 将是 2,因为有 2 个唯一用户。同样,prod a 和 prod c 将是 3。而在第二个矩阵中,它们将是 2 和 1。Thankx

标签: r matrix unique combinations cross-product


【解决方案1】:

试试

lst <- split(df$Users, df$Products)
ln <- length(lst)
m1 <-  matrix(0, ln,ln, dimnames=list(names(lst), names(lst)))
m1[lower.tri(m1, diag=FALSE)] <- combn(seq_along(lst), 2, 
               FUN= function(x) length(unique(unlist(lst[x]))))
m1[upper.tri(m1)] <- m1[lower.tri(m1)]
m1
#          Product a Product b Product c
#Product a         0         2         3
#Product b         2         0         3
#Product c         3         3         0

或使用outer

f1 <- function(u, v) length(unique(unlist(c(lst[[u]], lst[[v]]))))
res <- outer(seq_along(lst), seq_along(lst), FUN= Vectorize(f1)) *!diag(3)
dimnames(res) <- rep(list(names(lst)),2)
res
#          Product a Product b Product c
#Product a         0         2         3
#Product b         2         0         3
#Product c         3         3         0

对于第二种情况

tcrossprod(table(df))*!diag(3)
#            Products
#Products    Product a Product b Product c
# Product a         0         2         1
# Product b         2         0         1
# Product c         1         1         0

【讨论】:

  • 感谢您的帮助。这正是我想要的。
  • @prasara 很高兴为您提供帮助。
  • 如果想要三个产品组合的数据,最好的方法是什么。因此,我想查看使用产品 a 或产品 b 的唯一用户。示例:产品 a+产品 b+产品 c = 3 产品 a+产品 b+产品 d = 5。
  • @prasara 请将其作为一个单独的问题发布。
  • 谢谢 - 我发布了一个新问题 - link
猜你喜欢
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
  • 2018-09-07
  • 2011-04-28
  • 2011-06-20
  • 1970-01-01
  • 2015-02-23
相关资源
最近更新 更多