我有数据显示客户购买了某些商品。他们可以多次购买商品。我需要的是一张表格,其中显示了所有可能的项目成对组合以及购买该组合的客户的唯一数量(表格的对角线将是购买每个项目的唯一人数)。
以下是一个例子:
item <- c("h","h","h","j","j")
customer <- c("a","a","b","b","b")
test.data <- data.frame(item,customer)
这是test.data:
item customer
h a
h a
h b
j b
j b
需要的结果 - 包含行和列名称的项目的表格,以及在表格内购买该对的唯一客户的计数。因此,2个客户购买了商品h,1个购买了商品h和j,1个购买了商品j。
item h j
h 2 1
j 1 1
我尝试过使用表函数melt
/ cast
等,但没有任何东西可以让我获得表中所需的计数。我的第一步是使用unique()
来删除重复的行。
答案 0 :(得分:5)
使用data.table
和gtools
包,我们可以按客户重新创建所有可能的排列:
library(data.table)
library(gtools)
item <- c("h","h","h","j","j")
customer <- c("a","a","b","b","b")
test.data <- data.table(item,customer)
DT <- unique(test.data) #The unique is used as multiple purchases do not count twice
tuples <- function(x){
return(data.frame(permutations(length(x), 2, x, repeats.allowed = T, set = F), stringsAsFactors = F))
}
DO <- DT[, tuples(item), by = customer]
这给出了:
customer X1 X2
1: a h h
2: b h h
3: b h j
4: b j h
5: b j j
这是客户拥有的所有唯一商品配对的列表。根据你的例子,我们将j x j与j x h区别对待。我们现在可以使用表函数获得每对的频率:
table(DO$X1,DO$X2)
j h
j 1 1
h 1 2
答案 1 :(得分:5)
这是一个基础R解决方案:
n_intersect <- Vectorize( function(x,y) length(intersect(x,y)) )
cs_by_item <- with(test.data, tapply(customer, item, unique))
outer(cs_by_item , cs_by_item , n_intersect)
# h j
# h 2 1
# j 1 1