【发布时间】:2020-01-09 17:19:59
【问题描述】:
我对 lists 的使用还很陌生,所以如果这个问题听起来很愚蠢,我深表歉意。
从 459,046 名客户的原始集合中,我创建了一个函数,该函数将基础拆分并存储在列表的多个元素中。
sampled_list <- baseSample(dataset = clv_df_cbs, sample.size = 10000, seed = 12345)
执行此函数(baseSample),您将获得一个新的对象列表,其中包含互斥的客户组(每个组将由 10,000 个客户组成 - 除了最后一个可能更小,取决于初始音量)
> sampled_list <- baseSample(dataset = clv_df_cbs, sample.size = 10000, seed = 12345)
[1] "Seed: 12345"
[1] "Total groups created: 46"
[1] "Group size: 10000"
在这种情况下,输出是存储在名为 sample_list 的对象中的 46 个元素的列表。
现在,我想将这 46 个元素中的每一个都传递给一个 BTYD 模型,该模型将预测未来 90 天的交易数量(根据输入的学习情况)。
我无法将完整数据集传递给 BTYD 模型的原因是因为该模型大量使用 mcmc,因此有很长时间的计算导致模型停止提供任何输出。因此,我决定多次运行同一模型(在足够大的样本上)生成预测,直到我设法将所有基础作为模型输入。
需要对每个元素进行的操作如下
# Estimate parameters for element1 of the list
pggg.draws1 <- pggg.mcmc.DrawParameters(element1,
mcmc = 1000, # number of MCMC steps
burnin = 250, # number of initial MCMC steps which are discarded
thin = 10, # only every thin-th MCMC step will be returned
chains = 2, # number of MCMC chains to be run
trace = 50) # print logging step every trace iteration
# generate draws for holdout period
pggg.xstar.draws1 <- mcmc.DrawFutureTransactions(element1, pggg.draws1)
# conditional expectations
element1$xstar.pggg <- apply(pggg.xstar.draws1, 2, mean)
# P(active)
element1$pactive.pggg <- mcmc.PActive(pggg.xstar.draws1)
# P(alive)
element1$palive.pggg <- mcmc.PAlive(pggg.draws1)
# show estimates for first few customers
head(element1[, c("x", "t.x", "x.star",
"xstar.pggg", "pactive.pggg", "palive.pggg")],50)
# report median cohort-level parameter estimates
round(apply(as.matrix(pggg.draws1$level_2), 2, median), 3)
# report mean over median individual-level parameter estimates
median.est1 <- sapply(pggg.draws1$level_1, function(draw) {
apply(as.matrix(draw), 2, median)
})
round(apply(median.est1, 1, mean), 3)
理想情况下,输出应该直接存储到新的 data.frame 中 - 这样我就可以检索 Id 和预测(以及最初包含在数据集中的其他内容)。
下面是一些来自公开数据集的模拟数据。
library(BTYDplus)
library(tidyverse)
data("groceryElog")
dataset<-elog2cbs(groceryElog, T.cal = "2006-12-01")
# FUNCTION baseSample ####
baseSample <- function(dataset, sample.size, seed=NULL) {
seed.value <- if(is.null(seed)) {
as.numeric(format(Sys.Date(),"%Y"))*10000+as.numeric(format(Sys.Date(),"%m"))*100+as.numeric(format(Sys.Date(),"%d"))
} else {
seed
}
set.seed(seed.value)
# RE-ORDER DATA FRAME (SAME LENGTH)
data <- with(dataset, dataset[order(sample(cust, nrow(dataset))),])
# BUILD A LIST OF DFs
set.sample.size <- sample.size
data$cycles_group <- paste0("sample_", ceiling(1:nrow(data)/set.sample.size))
df_list <- split(data, data$cycles_group)
print(paste0("Seed: ", seed.value))
print(paste0("Total groups created: ", length(unique(data$cycles_group))))
print(paste0("Group size: ", set.sample.size))
return(df_list)
#print(df_list)
}
# ** OUTPUT: Base split in lists ####
sampled_list <- baseSample(dataset = dataset, sample.size = 100, seed = 12345)
谢谢
【问题讨论】:
-
您可以在基础 R 中执行此操作,方法是将所有这些操作包装在对
lapply的调用中的函数中,然后使用类似newdf <- do.call(rbind, [list outputted by lapply])的内容将结果汇总到新的数据帧中。 -
嗨!谢谢你的评论。你能说得具体一点吗?如果您考虑最后一段脚本(示例),您如何创建您提到的 [lapply 输出的列表]?