计算每组可能的所有对

时间:2017-01-14 20:53:42

标签: r dplyr

我找不到相关的帖子,但是如果有类似的问题被提出并回答道歉。如果我有以下数据:

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

3 个答案:

答案 0 :(得分:2)

在具有Test == 1:

的行中看起来像table的作业
 (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

答案 1 :(得分:1)

以下是仅使用基础R.我们在aggregateMarket的想法,并在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

答案 2 :(得分:0)

下面的n.markets函数会给出您想要的计数矩阵。前两行给出产品对,例如第一列显示对1&amp; 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

编辑:user20650评论的答案要快得多

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