【发布时间】:2018-01-15 09:02:19
【问题描述】:
根据标题,我希望与一个表进行交叉连接,该表执行聚合函数并过滤表中的几个变量。
我有以下类似的数据:
library(dplyr)
library(data.table)
library(sqldf)
sales <- data.frame(salesx = c(3000, 2250,850,1800,1700,560,58,200,965,1525)
,week = seq(from = 1, to = 10, by = 1)
,uplift = c(0.04)
,slope = c(100)
,carryover = c(.35))
spend <- data.frame(spend = seq(from = 1, to = 50000, by = 1))
tempdata <- merge(spend,sales,all=TRUE)
tempdata$singledata <- as.numeric(1)
下面是我试图通过基于 sql 的解决方案完成的示例:
newdata <- sqldf("select a.spend, a.week,
sum(case when b.week > a.week
then b.salesx*(b.uplift*(1-exp(-(power(b.singledata,b.week-a.week)/b.slope))))/b.spend
else 0.0 end) as calc3
from tempdata a, tempdata b
where a.spend = b.spend
group by a.spend,a.week")
这提供了我想要的结果,但它有点慢,尤其是在我的真实数据集大约 100 万条记录的情况下。最好有一些关于 a) 如何加速 sqldf 函数的建议;或 b) 使用更有效的 data.table/dplyr 方法(我无法解决交叉连接/聚合/过滤三重奏问题)。
以下非 equi 连接解决方案的明确性:
我有几个关于非 equi 连接解决方案的问题 - 输出很好而且非常快。为了了解代码的工作原理,我将其分解如下:
breakdown <- setDT(tempdata)[tempdata, .(spend, uplift, slope,carryover,salesx, singledata, week, i.week,x.week, i.salesx,x.salesx, x.spend, i.spend), on=.(spend, week > week)]
根据细分,为了和原来的计算一致,应该是:
x.salesx*(uplift*(1.0-exp(-(`^`(singledata,x.week-week)/slope))))/i.spend
这不明显的原因是因为在示例中,我使用了等式的“功率”部分并没有真正做任何事情(始终为 1)。实际使用的计算是(向数据添加结转变量):
SQL
b.salesx*(b.uplift*(1-exp(-(power((b.singledata*b.carryover),b.week-a.week)/b.slope))))/b.spend (sql)
我的 data.table 解决方案
sum(salesx.y*(uplift.y*(1-exp(-((singledata.y*adstock.y)^(week.y-week.x)/slope.y))))/spend), by=list(spend, week.x)
但是,当添加“carryover”变量时,我无法使用非 equi join 解决方案来实现这一点。
x.salesx*(uplift*(1.0-exp(-(`^`((singledata*carryover),x.week-week)/slope))))/i.spend
【问题讨论】:
-
你加载了
data.table,但是你什么也没做??? (通常最好将过程分解为多个步骤。) -
如果您添加索引,您也许可以让您现有的代码运行得更快。
-
或许,
data.table的非 equi-join 在这里可能会有所帮助。但是,请描述您的目标/意图是什么。除了您要求改进的现有解决方案之外,可能还有其他方法。
标签: r data.table dplyr sqldf cross-join