Согласно заголовку, я хочу выполнить перекрестное соединение с таблицей, которая выполняет функцию агрегирования и фильтрует пару переменных в таблице.
У меня есть данные, похожие на следующие:
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")
Это дает желаемые результаты, но это немного медленно, особенно с моим реальным набором данных, состоящим из около 1 миллиона записей. Было бы здорово получить совет: а) как ускорить работу функции sqldf; или б) с использованием более эффективного подхода data.table / dplyr (я не могу разобраться в проблеме перекрестного соединения / агрегации / фильтрации trifecta).
Разъяснение решения для неравномерного соединения ниже:
У меня было несколько вопросов о решении для неэквивалентного соединения - вывод нормальный и очень быстрый. Чтобы понять, как работает код, я разбил его так:
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)
Однако я не могу заставить это работать с решением неэквивалентного соединения при добавлении переменной «переходящего остатка», т.е.
x.salesx*(uplift*(1.0-exp(-(`^`((singledata*carryover),x.week-week)/slope))))/i.spend
data.table
, а потом ничего не делаешь ??? (вообще лучше разбить процесс на этапы.) - person IRTFM   schedule 08.08.2017data.table
. Но, пожалуйста, опишите, какова ваша цель / намерение. Могут быть другие подходы, помимо существующего решения, которое вы просите улучшить. - person Uwe   schedule 30.08.2017