Генерировать матрицу уникальных комбинаций товаров и товаров между пользователями
Я пытаюсь создать кросс-продуктовую матрицу уникальных пользователей в 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
Вторая матрица будет числом уникальных пользователей, у которых были оба продукта (И):
Product a Product b Product c
Product a 2 1
Product b 2 1
Product c 1 1
Любая помощь приветствуется.
Спасибо
ОБНОВИТЬ:
Для большей ясности: продукт А используется Пользователем1 и Пользователем2. Продукт b используется User1 и User2, а продукт c используется User1 и User3. Таким образом, в первой матрице Product a и Product b будут равны 2, поскольку есть 2 уникальных пользователя. Аналогично, Product a и Product c будут равны 3. Где, как и во второй матрице, они будут равны 2 и 1, поскольку я хочу пересечение. Спасибо
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