2017-01-14 2 views
1

Я не мог найти подходящее сообщение для этого, но извинения, если что-то подобное было задано и ответили. Если у меня есть следующие данные:Подсчитайте все возможные пары в группе

Market Product Test 
A  1  1 
A  2  1 
A  3  0 
A  4  1 
B  1  0 
B  2  0 
B  3  1 
B  4  1 
C  1  1 
C  2  1 
C  3  0 
C  4  0 

Если Test = 1, то продукт существует на рынке. Если я хочу подсчитать количество рынков, где два продукта сосуществуют для всех комбинаций продуктов и рынков, как мне это сделать? Например, 1 & 2 = 2; 1 & 3 = 0; 1 & 4 = 1.

Я уже рассчитали сумму рынков для каждого продукта с помощью dplyr:

Answer <- Data %>% 
      group_by(Market) %>% 
      summarise(ProductCount = sum(Test)) 
+1

Вы можете показать свой желаемый результат тоже пожалуйста ? –

+0

'tab = crossprod (таблица (d [d $ Test == 1, -3])); tab [lower.tri (tab, diag = TRUE)] <- NA; reshape2 :: melt (tab, na.rm = TRUE) '. Измените 'diag = FALSE', если вы хотите, чтобы количество счетов для каждого рынка – user20650

ответ

2

выглядит как работа для table в строках, которые имеют испытания == 1:

(combMkt <- with( Data[ Data$Test==1, ], table(Market, Product))) 
#-- the starting point of all Test=1 rows: 
     Product 
Market 1 2 3 4 
    A 1 1 0 1 
    B 0 0 1 1 
    C 1 1 0 0 

# Choose the ones with 2 or more Markets 
combMkt[ , which(apply(combMkt, 2, sum) >=2)] 
     Product 
Market 1 2 4 
    A 1 1 1 
    B 0 0 1 
    C 1 1 0 
0

Функция n.markets ниже дает матрицу подсчетов, которые вы хотите. Первые два ряда дают пару продуктов, например. в первом столбце показана пара 1 & 2, а в третьей строке дается счет рынка.

dat <- data.frame(Market = c(rep('A',4),rep('B',4),rep('C',4)), Product = rep(1:4,3), Test = c(1,1,0,1,0,0,1,1,1,1,0,0)) 


n.markets <- function(dat){ 
    combs <- combn(unique(dat$Product),2) 
    mkts <- unique(as.vector(dat$Market)) 
    counts <- rep(0,ncol(combs)) 
    for(j in 1:ncol(combs)){ 
     for(i in seq_along(mkts)){ 
      counts[j] <- counts[j] + (sum(dat[dat$Market==mkts[i] & dat$Product %in% combs[,j], 'Test'])==2) 
     } 
    } 
    rbind(combs,counts) 
} 

n.markets(dat) 

##  [,1] [,2] [,3] [,4] [,5] [,6] 
##   1 1 1 2 2 3 
##   2 3 4 3 4 4 
## counts 2 0 1 0 1 1 

Edit: Ответ на комментарий user20650 является гораздо быстрее

tab = crossprod(table(d[d$Test==1, -3])) 
tab[lower.tri(tab, diag=TRUE)] <- NA 
reshape2::melt(tab, na.rm=TRUE) 
1

Вот идея использовать только базовый R. Мы aggregate на Market и получить все возможные комбинации, когда Test == 1. Затем мы используем table считать пары и расположить их в data.frame

d1 <- aggregate(Product ~ Market, df[df$Test == 1,], FUN = function(i)combn(i, 2, FUN = toString)) 
d2 <- as.data.frame(table(unlist(d1$Product)), stringsAsFactors = FALSE) 

d2 
# Var1 Freq 
#1 1, 2 2 
#2 1, 4 1 
#3 2, 4 1 
#4 3, 4 1 

Однако, если вы хотите включить все пары не явившиеся, то

n <- setdiff(combn(unique(df$Product), 2, toString), d2$Var1) 
rbind(d2, data.frame(Var1 = n, Freq = 0, stringsAsFactors = FALSE)) 

# Var1 Freq 
#1 1, 2 2 
#2 1, 4 1 
#3 2, 4 1 
#4 3, 4 1 
#5 1, 3 0 
#6 2, 3 0 
Смежные вопросы