I am trying to mean center (aka demean, scale) a variable by 3 dimensions: year, month, and region using the sqldf
package in R.
Here is exactly what I want to do using the plyr
package:
## create example data
set.seed(145)
v = Sys.Date()-seq(1,425)
regions = LETTERS[1:6]
VAR1_DATA = as.data.frame(expand.grid(v,regions))
VAR1_DATA$VAR1 = rpois(nrow(VAR1_DATA), 4) + runif(nrow(VAR1_DATA), 25,35)
names(VAR1_DATA) = c("DATE","REG","VAR1")
## mean center VAR1 by year, month and region using plyr:
lapply(c('chron','plyr'), require, character.only=T)
table1 = cbind(MONTH = months(as.POSIXlt(VAR1_DATA[,'DATE'])),
YEAR = years(as.POSIXlt(VAR1_DATA[,'DATE'])),
VAR1_DATA)
table2 = ddply(table1, c('YEAR','MONTH','REG'), transform, MEAN.V1 = mean(VAR1), DEMEANED.V1 = VAR1 - mean(VAR1))
head(table2)
## MONTH YEAR DATE REG VAR1 MEAN.V1 DEMEANED.V1
## 1 December 2011 2011-12-31 A 30.03605 34.69316 -4.6571064
## 2 December 2011 2011-12-30 A 31.69130 34.69316 -3.0018600
## 3 December 2011 2011-12-29 A 35.46342 34.69316 0.7702634
## 4 December 2011 2011-12-28 A 32.09727 34.69316 -2.5958876
## 5 December 2011 2011-12-27 A 36.51519 34.69316 1.8220386
## 6 December 2011 2011-12-26 A 35.65338 34.69316 0.9602236
Now I would like to replicate the result above using SQLite / SQL. Below is the SQLite code I'm currently using to attempt to accomplish this (Warning: the code below does not work!). I have included it here to illustrate my SQLish thought process:
require(sqldf)
sqldf("
SELECT
strftime('%m', t1.DATE) AS 'MONTH',
strftime('%Y', t1.DATE) AS 'YEAR',
t1.DATE,
t1.REG,
t1.VAR1,
t2.MVAR1 AS 'MO_AVG_VAR1',
(t1.VAR1-t2.MVAR1) AS 'DEMEANED_VAR1',
FROM VAR1_DATA AS t1,
(
SELECT
DATE,
REG,
avg(VAR1) AS MVAR1,
FROM VAR1_DATA
GROUP BY strftime('%Y', DATE), strftime('%m', DATE), REG
) AS t2
WHERE t1.REGION = t2.REGION
AND t1.DATE = t2.DATE
GROUP BY strftime('%Y', t1.DATE), strftime('%m', t1.DATE), t1.REGION
ORDER BY YEAR, MONTH, REG
;")
Question: is this calculation possible in SQLite / sqldf -- if so, how? Bonus points if the answer also provides the (slightly modified?) "regular SQL" (i.e. mySQL, PostgreSQL, etc.) implementation.
Many thanks!