2015-06-27 2 views
2

Я пытаюсь создать матрицу кросс-продуктов уникальных пользователей в R. Я искал ее на SO, но не смог найти то, что искал. Любая помощь приветствуется. У меня есть большой dataframe (более миллиона) и образец показано:Создайте матрицу уникальных комбинаций продуктов из пользовательского элемента

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')) 

Выход ФР:

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 

Я хотел бы видеть две матрицы: Первый из них будет показывать количество уникальных пользователей, которые были либо продукты (OR) - так что выход будет что-то вроде:

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

Вторая матрица будет количество уникальных U (И):

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

Любая помощь приветствуется.

Благодаря

UPDATE:

Вот больше ясности: продукт А используется user1 и user2. Продукт b используется User1 и User2, а Product c используется User1 и User3. Таким образом, в первой матрице Product a и Product b будут 2, поскольку есть 2 уникальных пользователя. Аналогично, Product a и Product c будут 3. Где, как и во второй матрице, они будут 2 и 1, так как я хочу пересечение. Благодаря

+3

число в ожидаемом выходе представляет ли значение в примере показало? Для второго случая может быть 'tbl <- table (merge (df, df, by.x = 'Users', by.y = 'Users') [- 1]); diag (tbl) <- 0' – akrun

+3

@akrun Я согласен с вами ... выход df выборки, похоже, не согласуется с желаемым выходом. –

+0

@TimBiegeleisen Первый случай не ясен. Я получаю ожидаемый результат для второго – akrun

ответ

5

Try

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 
+1

Спасибо за помощь. Это именно то, что я искал. – prasara

+0

@prasara Рад помочь вам. – akrun

+0

Если хотите данные с комбинацией наборов из трех продуктов, каким будет лучший способ. Итак, я хочу видеть уникальных пользователей, которые использовали продукт OR product b. Пример: Продукт a + Продукт b + Продукт c = 3 Продукт a + Продукт b + Продукт d = 5. – prasara

Смежные вопросы