2

R で一意のユーザーのクロスプロダクト マトリックスを作成しようとしています。SO で検索しましたが、探しているものが見つかりませんでした。どんな助けでも大歓迎です。大きなデータフレーム (100 万以上) があり、サンプルが表示されます。

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

2 つのマトリックスを確認したいと思います。最初のマトリックスは、いずれかの製品 (OR) を持っていたユニーク ユーザーの数を示します。したがって、出力は次のようになります。

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

2 番目のマトリックスは、両方の製品 (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 番目のマトリックスと同様に、交点が必要なので、2 と 1 になります。ありがとう

4

1 に答える 1

5

試す

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

2番目のケースの場合

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
于 2015-06-27T14:15:30.140 に答える