我有一份以数据框形式购买这些产品的产品和客户名单
client product
001 pants
001 shirt
001 pants
002 pants
002 shirt
002 shoes
我需要重新订购tuplas中的产品,并添加第三列,其中包含购买这两种产品的客户数量。 解决方案将是两个不同的表,一个具有唯一的客户端,另一个具有总购买的元组。 所以前面的例子,结果将是:
product1 product2 count
pants shirt 2
pants shoes 1
shirt shoes 1
product1 product2 count
pants shirt 3
pants shoes 1
shirt shoes 1
我想避免重复的信息。例如,一排衬衫裤子2'不需要。
有人会知道怎么做吗?
谢谢!
答案 0 :(得分:1)
这可能不是最有效的方式,也不是最优雅的方式,但它可以满足您的需求。鉴于您的初始列名是'客户'和'产品',
library(stringr)
Count.Sales <- function(df){
df3 <- as.data.frame(t(combn(paste0(df$client, df$product), 2)))
df4 <- as.data.frame(table(df3[str_extract(df3$V1, '[[:digit:]]+') == str_extract(df3$V2, '[[:digit:]]+'),]))
df4 <- subset(df4, df4$Freq > 0)
df4$customer <- str_extract(df4$V1, '[[:digit:]]+')
df4[, !(colnames(df4) %in% c("Freq","customer"))] <- apply(df4[, !(colnames(df4) %in% c("Freq","customer"))], 2, function(i) sub('[[:digit:]]+', '', i))
new.df<- within(df4, rm(Freq))
new.df[] <- lapply(new.df, as.character)
r1 <- apply(new.df[,-3], 1, function(i)any(i[-1] != i[1]))
new.df <- new.df[r1,]
new.df$pairs <- do.call(paste, c(new.df[,-3], ' '))
new.df$pairs <- vapply(new.df$pairs, function(i) paste(sort(strsplit(i, ' ')[[1]]), collapse=' '), ' ')
t4 <- data.frame(with(new.df, table(pairs, customer)))
t4 <- t4[t4$Freq != 0,]
per_customer <- as.data.frame(table(t4$pairs))
total <- as.data.frame(table(new.df$pairs))
ls1 <- list(per_customer, total)
names(ls1) <- c('Unique.Customer', 'Total')
return(ls1)
}
Count.Sales(df)
#$Unique.Customer
# Var1 Freq
#1 pants shirt 2
#2 pants shoes 1
#3 shirt shoes 1
#
#$Total
# Var1 Freq
#1 pants shirt 3
#2 pants shoes 1
#3 shirt shoes 1