2014-03-12 48 views
0
「應急」表

讓我們考慮這個數據集,其中第一場是單號,第二個是產品的名稱:創建多行

df=data.frame(bill=c(1,1,1,1,2,2,2,2,3,3),product=c("A","B","C","B","A","C","E","D","C","D")) 

我想算號含在這種情況下兩種產品的每一種組合,例如賬單這樣的結果(我不想讓這些組合中計數爲0):

# prod1 prod2 count 
# A  B  1 
# A  C  2 
# A  D  1 
# A  E  1 
# B  C  1 
# C  D  2 
# C  E  1 
# D  E  1 

我有一個循環的解決方案,但它真的不是漂亮(而且慢!):

products=sort(unique(df$product)) 
bills_list=list() 
for (i in 1:length(products)){ 
    bills_list[[i]]=unique(df[which(df$product==products[i]),"bill"]) 
} 
df2=data.frame(prod1=character(0),prod2=character(0),count=numeric(0)) 
for (i in 1:(length(products)-1)){ 
    for (j in (i+1):length(products)){ 
     Nij=length(intersect(bills_list[[i]],bills_list[[j]])) 
     if (Nij>0){ 
     temp=data.frame(prod1=products[i],prod2=products[j],count=Nij) 
     df2=rbind(df2,temp) 
     } 
    } 
} 

有沒有辦法做到這一點沒有循環? 謝謝你的時間。

回答

1

這是plyrdata.table的解決方案。

# needed packages 
require(plyr) 
require(data.table) 
# find the combinations in each of the bills 
combs <- ddply(df, .(bill), function(x){ 
    t(combn(unique(as.character(x$product)),2)) 
}) 
colnames(combs) <- c("bill", "prod1", "prod2") 
# combine these 
res <- data.table(combs, key=c("prod1", "prod2"))[, .N, by=list(prod1, prod2)] 
+0

+1比我的回答更優雅! –

+0

完美!謝謝 ! – fmarm

1
library(reshape2) 

df$product <- as.character(df$product) 
products <- t(combn(unique(df$product), 2)) 
dat <- dcast(bill ~ product, data = df) 
## bill A B C D E 
## 1 1 1 2 1 0 0 
## 2 2 1 0 1 1 1 
## 3 3 0 0 1 1 0 


out <- structure(
    data.frame(products, apply(products, 1, function(x) sum(rowSums(dat[x] > 0) == 2))), 
    names = c("prod1", "prod2", "count") 
) 

out[out$count != 0,] 
## prod1 prod2 count 
## 1  A  B  1 
## 2  A  C  2 
## 3  A  E  1 
## 4  A  D  1 
## 5  B  C  1 
## 8  C  E  1 
## 9  C  D  2 
## 10  E  D  1 
1

這裏的另一種方法:

library(qdap) 

dat <- unlist(lapply(split(df$product, df$bill), function(x) { 
    y <- outer(unique(x), unique(x), paste) 
    unlist(y[upper.tri(y)]) 
})) 

dat2 <- data.frame(table(dat), stringsAsFactors = FALSE) 

colsplit2df(dat2, sep=" ", new.names=paste0("prod", 1:2)) 

## prod1 prod2 Freq 
## 1  A  B 1 
## 2  A  C 2 
## 3  A  D 1 
## 4  A  E 1 
## 5  B  C 1 
## 6  C  D 2 
## 7  C  E 1 
## 8  E  D 1 
0
res <- table(df$bill, df$product) 
##> res 
## 
## A B C D E 
## 1 1 2 1 0 0 
## 2 1 0 1 1 1 
## 3 0 0 1 1 0 

res2 <- ifelse(res > 0, 1, 0) 
##> res2 
## 
## A B C D E 
## 1 1 1 1 0 0 
## 2 1 0 1 1 1 
## 3 0 0 1 1 0 

cor(res2) 
## 
##  A B C D E 
##A 1.0 0.5 NA -0.5 0.5 
##B 0.5 1.0 NA -1.0 -0.5 
##C NA NA 1 NA NA 
##D -0.5 -1.0 NA 1.0 0.5 
##E 0.5 -0.5 NA 0.5 1.0 
##Warning message: 
##In cor(res2) : the standard deviation is zero 

我也知道這不回答你問的問題。

但是,它可能會讓你更接近答案,大概是你尋求的。也就是說,客戶訂購一種產品對可能性(正面或負面)的影響是什麼,會訂購其中一種產品。

+0

而且,沒有要安裝,學習和更新的軟件包。 – user3229754