2017-01-14 5 views
1

Ich konnte keinen relevanten Beitrag dafür finden, aber Entschuldigung, wenn etwas ähnliches gefragt und beantwortet wurde. Wenn ich folgende Daten habe:Zählen Sie alle möglichen Paare pro Gruppe

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 

Wenn Test = 1, dann existiert ein Produkt auf einem Markt. Wenn ich die Anzahl der Märkte, in denen zwei Produkte für alle Produkt-Markt-Kombinationen nebeneinander bestehen, zählen möchte, wie mache ich das? Zum Beispiel 1 & 2 = 2; 1 & 3 = 0; 1 & 4 = 1.

ich bereits die Summe der Märkte für jedes Produkt berechnet dplyr:

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

Können Sie Ihre gewünschte Ausgabe zeigen auch bitte ? –

+0

'tab = crossprod (Tabelle (d [d $ Test == 1, -3])); tab [lower.tri (tab, diag = TRUE)] <- NA; reshape2 :: melt (tab, na.rm = TRUE) '. Ändern Sie 'diag = FALSE ', wenn Sie die Anzahl der Zählungen für jeden Markt möchten – user20650

Antwort

2

Sieht aus wie ein Job für table in Zeilen, die Test-== haben 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

Die folgende Funktion n.markets enthält eine Matrix der von Ihnen gewünschten Anzahl. Die ersten zwei Reihen ergeben das Produktpaar, z.B. die erste Spalte zeigt das Paar 1 & 2, und die dritte Zeile gibt den Markt an.

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: Die Antwort auf Kommentar des user20650 ist viel schneller

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

Hier ist eine Idee, nur Basis R. Wir aggregate auf Market verwenden und alle möglichen Kombinationen erhalten, wenn Test == 1. Wir verwenden table dann die Paare zu zählen und ordnen sie in einem 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 

jedoch Wenn Sie alle Paare nicht erscheinen, enthalten sein sollen, dann,

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 
Verwandte Themen