我正忙着建立一个推荐系统。我有某些用户的历史购买。
我的数据显示为
> head(baskets)
# A tibble: 6 x 2
# Groups: user_id [2]
user_id basket
<int> <list>
1 8 <int [21]>
2 8 <int [13]>
3 8 <int [15]>
4 12 <int [22]>
5 12 <int [20]>
6 12 <int [17]>
> baskets$basket[[1]]
[1] 651 1529 2078 6141 6473 9839 14992 16349 17794 20920 21903
[12] 23165 23400 24838 28985 32030 34190 39110 39812 44099 49533
好的,现在我想从每个篮子中删除一个项目并将其保存为目标项目,并将剩余的篮子保存为新篮子。对于篮子中的所有物品,将重复此操作。如果我们有例如user_id = 1和basket = [1,2,3]的用户,我们会得到
user_id basket target
1 2,3 1
1 1,3 2
1 1,2 3
如何以有效的方式构建这样的data.frame / tibble?我有一个解决方案,但似乎工作很慢,因为我有大量的数据,我想找到一个更好的解决方案,如果可能的话。
目前我有
orderdf <- data.frame(user_id = integer(), basket = list(), target =
integer())
for(k in 1:dim(baskets)[1]){
print(k)
currbasket <- baskets$basket[[k]]
currbaskets <- lapply(1:length(currbasket), function(i) currbasket[i])
curruser <- baskets$user_id[k]
for(j in 1:length(currbaskets)){
tempdf <- tibble(user_id = baskets$user_id[k], basket =
list(currbaskets[[j]]), target = currbasket[j])
orderdf <- rbind(orderdf, tempdf)
}
}
答案 0 :(得分:1)
首先,我创建了一个可复制的数据集
baskets <- data.frame(user_id = 1:10)
for (i in 1:nrow(df)){
baskets$basket[i] = list(sample(1:100, 3, replace=F))
}
head(baskets)
下次请提供可复制的设置!
接下来要做的是构建一个处理一行的函数:
x = baskets[1,]
x$basket = x$basket[[1]]
require(data.table)
foraline <- function(x){
n_inbasket <- length(unlist(x$basket))
result <- data.table(user_id = rep(x$user_id, n_inbasket))
result$basket <- sapply(1:n_inbasket, function(i){list(unlist(x$basket)[-i])})
result$target <- x$basket
return(result)
}
foraline(x)
好的,现在,我们将它应用于所有行,并使用data.table包中的rbindlist
在一个data.frame中减少它。
require(data.table)
order_basket <- rbindlist(apply(baskets, 1, foraline))
head(order_basket)