Skip to content

Commit

Permalink
deprecate drift argument; allow intercepts in all trend_formula model…
Browse files Browse the repository at this point in the history
…s and update docs appropriately
  • Loading branch information
Nicholas Clark committed Jul 5, 2024
1 parent 87c6077 commit 5b9d09b
Show file tree
Hide file tree
Showing 110 changed files with 823 additions and 818 deletions.
10 changes: 8 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# mvgam 1.1.3
# mvgam 1.1.3 (development version; not yet on CRAN)
## New functionalities
* Added option for process model intercept parameter to be included when a `trend_map` is supplied. This breaks the assumption that the process has to be zero-centred, adding flexibility but also potentially inducing nonidentifiabilities with respect to any observation model intercepts. Thoughtful priors are a must for these models
* Allow intercepts to be included in process models when `trend_formula` is supplied. This breaks the assumption that the process has to be zero-centred, adding flexibility but also potentially inducing nonidentifiabilities with respect to any observation model intercepts. Thoughtful priors are a must for these models

## Deprecations
* The `drift` argument has been deprecated. It is now recommended for users to include parametric fixed effects of "time" in their respective GAM formulae to capture any expected drift effects

## Bug fixes
* Added a new check to ensure that exception messages are only suppressed by the `silent` argument if the user's version of 'cmdstanr' is adequate

# mvgam 1.1.2
## New functionalities
Expand Down
44 changes: 16 additions & 28 deletions R/add_MACor.R
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ add_MaCor = function(model_file,
model_file[to_modify] <-
paste0('// derived latent states\n',
'LV[1] = ',
if(drift){ 'drift + '} else {NULL},
'trend_mus[ytimes_trend[1, 1:n_lv]] + error[1];\n',
if(add_ma){
'epsilon[1] = error[1];\n'
Expand All @@ -167,7 +166,7 @@ add_MaCor = function(model_file,
'// full AR process\n'
},
'LV[i] = ',
if(drift){ 'drift + '} else {NULL},
if(drift){ 'drift * (i - 1) + '} else {NULL},
'trend_mus[ytimes_trend[i, 1:n_lv]] + ',
if(trend_model == 'AR1'){ 'ar1 .* '} else {NULL},
'(LV[i - 1] - trend_mus[ytimes_trend[i - 1, 1:n_lv]])',
Expand All @@ -191,7 +190,6 @@ add_MaCor = function(model_file,
model_file[to_modify] <-
paste0('// derived latent states\n',
'LV[1] = ',
if(drift){ 'drift + '} else {NULL},
'trend_mus[ytimes_trend[1, 1:n_lv]] + error[1];\n',
if(add_ma){
paste0('epsilon[1] = error[1];\n',
Expand All @@ -217,7 +215,7 @@ add_MaCor = function(model_file,
'// full AR process\n'
},
'LV[i] = ',
if(drift){ 'drift + '} else {NULL},
if(drift){ 'drift * (i - 1) + '} else {NULL},
'trend_mus[ytimes_trend[i, 1:n_lv]] + ',
'ar1 .* (LV[i - 1] - trend_mus[ytimes_trend[i - 1, 1:n_lv]]) + ',
'ar2 .* (LV[i - 2] - trend_mus[ytimes_trend[i - 2, 1:n_lv]]) + ',
Expand All @@ -241,7 +239,6 @@ add_MaCor = function(model_file,
model_file[to_modify] <-
paste0('// derived latent states\n',
'LV[1] = ',
if(drift){ 'drift + '} else {NULL},
'trend_mus[ytimes_trend[1, 1:n_lv]] + error[1];\n',
if(add_ma){
paste0('epsilon[1] = error[1];\n',
Expand All @@ -260,7 +257,7 @@ add_MaCor = function(model_file,
'error[2];\n'
},
'LV[3] = ',
if(drift){ 'drift + '} else {NULL},
if(drift){ 'drift * 2 + '} else {NULL},
'trend_mus[ytimes_trend[3, 1:n_lv]] + ',
'ar1 .* (LV[2] - trend_mus[ytimes_trend[2, 1:n_lv]]) + ',
'ar2 .* (LV[1] - trend_mus[ytimes_trend[1, 1:n_lv]]) + ',
Expand All @@ -278,7 +275,7 @@ add_MaCor = function(model_file,
'// full AR process\n'
},
'LV[i] = ',
if(drift){ 'drift + '} else {NULL},
if(drift){ 'drift * (i - 1) + '} else {NULL},
'trend_mus[ytimes_trend[i, 1:n_lv]] + ',
'ar1 .* (LV[i - 1] - trend_mus[ytimes_trend[i - 1, 1:n_lv]]) + ',
'ar2 .* (LV[i - 2] - trend_mus[ytimes_trend[i - 2, 1:n_lv]]) + ',
Expand All @@ -305,15 +302,14 @@ add_MaCor = function(model_file,
paste0('// derived latent states\n',
'for(j in 1:n_lv){\n',
'LV[1, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
'trend_mus[ytimes_trend[1, j]] + error[1, j];\n',
'epsilon[1, j] = error[1, j];\n',
'for(i in 2:n){\n',
'// lagged error ma process\n',
'epsilon[i, j] = theta[j] * error[i-1, j];\n',
'// full ARMA process\n',
'LV[i, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
if(drift){ 'drift[j] * (i - 1) + '} else {NULL},
'trend_mus[ytimes_trend[i, j]] + ',
if(trend_model == 'AR1'){ 'ar1[j] * '} else {NULL},
'(LV[i - 1, j] - trend_mus[ytimes_trend[i - 1, j]]) + ',
Expand All @@ -334,7 +330,6 @@ add_MaCor = function(model_file,
paste0('// derived latent states\n',
'for(j in 1:n_lv){\n',
'LV[1, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
'trend_mus[ytimes_trend[1, j]] + error[1, j];\n',
'epsilon[1, j] = error[1, j];\n',
'epsilon[2, j] = theta[j] * error[1, j];\n',
Expand All @@ -348,7 +343,7 @@ add_MaCor = function(model_file,
'epsilon[i, j] = theta[j] * error[i-1, j];\n',
'// full ARMA process\n',
'LV[i, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
if(drift){ 'drift[j] * (i - 1) + '} else {NULL},
'trend_mus[ytimes_trend[i, j]] + ',
'ar1[j] * (LV[i - 1, j] - trend_mus[ytimes_trend[i - 1, j]]) + ',
'ar2[j] * (LV[i - 2, j] - trend_mus[ytimes_trend[i - 2, j]]) + ',
Expand All @@ -369,7 +364,6 @@ add_MaCor = function(model_file,
paste0('// derived latent states\n',
'for(j in 1:n_lv){\n',
'LV[1, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
'trend_mus[ytimes_trend[1, j]] + error[1, j];\n',
'epsilon[1, j] = error[1, j];\n',
'epsilon[2, j] = theta[j] * error[1, j];\n',
Expand All @@ -380,7 +374,7 @@ add_MaCor = function(model_file,
'ar1[j] * (LV[1, j] - trend_mus[ytimes_trend[1, j]]) + ',
'epsilon[2, j] + error[2, j];\n',
'LV[3, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
if(drift){ 'drift[j] * 2 + '} else {NULL},
'trend_mus[ytimes_trend[1, j]] + ',
'ar1[j] * (LV[2, j] - trend_mus[ytimes_trend[2, j]]) + ',
'ar2[j] * (LV[1, j] - trend_mus[ytimes_trend[1, j]]) + ',
Expand All @@ -390,7 +384,7 @@ add_MaCor = function(model_file,
'epsilon[i, j] = theta[j] * error[i-1, j];\n',
'// full ARMA process\n',
'LV[i, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
if(drift){ 'drift[j] * (i - 1) + '} else {NULL},
'trend_mus[ytimes_trend[i, j]] + ',
'ar1[j] * (LV[i - 1, j] - trend_mus[ytimes_trend[i - 1, j]]) + ',
'ar2[j] * (LV[i - 2, j] - trend_mus[ytimes_trend[i - 2, j]]) + ',
Expand Down Expand Up @@ -446,7 +440,6 @@ add_MaCor = function(model_file,
paste0(model_file[insert_line],
'\n// derived latent states\n',
'trend_raw[1] = ',
if(drift){ 'drift + '} else {NULL},
'error[1];\n',
if(add_ma){
'epsilon[1] = error[1];\n'
Expand All @@ -462,7 +455,7 @@ add_MaCor = function(model_file,
paste0('// full AR process\n')
},
'trend_raw[i] = ',
if(drift){ 'drift + '} else {NULL},
if(drift){ 'drift * (i - 1) + '} else {NULL},
if(trend_model == 'AR1'){ 'ar1 .* '} else {NULL},
'trend_raw[i - 1] + ',
if(add_ma){
Expand All @@ -487,7 +480,6 @@ add_MaCor = function(model_file,
paste0(model_file[insert_line],
'\n// derived latent states\n',
'trend_raw[1] = ',
if(drift){ 'drift + '} else {NULL},
'error[1];\n',
if(add_ma){
paste0('epsilon[1] = error[1];\n',
Expand All @@ -512,7 +504,7 @@ add_MaCor = function(model_file,
'// full AR process\n'
},
'trend_raw[i] = ',
if(drift){ 'drift + '} else {NULL},
if(drift){ 'drift * (i - 1) + '} else {NULL},
'ar1 .* trend_raw[i - 1] + ',
'ar2 .* trend_raw[i - 2] + ',
if(add_ma){
Expand All @@ -537,7 +529,6 @@ add_MaCor = function(model_file,
paste0(model_file[insert_line],
'\n// derived latent states\n',
'trend_raw[1] = ',
if(drift){ 'drift + '} else {NULL},
'error[1];\n',
if(add_ma){
paste0('epsilon[1] = error[1];\n',
Expand All @@ -555,7 +546,7 @@ add_MaCor = function(model_file,
'error[2];\n'
},
'trend_raw[3] = ',
if(drift){ 'drift + '} else {NULL},
if(drift){ 'drift * 2 + '} else {NULL},
'ar1 .* trend_raw[2] + ',
'ar2 .* trend_raw[1] + ',
if(add_ma){
Expand All @@ -572,7 +563,7 @@ add_MaCor = function(model_file,
'// full AR process\n'
},
'trend_raw[i] = ',
if(drift){ 'drift + '} else {NULL},
if(drift){ 'drift * (i - 1) + '} else {NULL},
'ar1 .* trend_raw[i - 1] + ',
'ar2 .* trend_raw[i - 2] + ',
'ar3 .* trend_raw[i - 3] + ',
Expand All @@ -599,15 +590,14 @@ add_MaCor = function(model_file,
paste0(model_file[insert_line],
'\nfor(j in 1:n_series){\n',
'trend[1, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
'error[1, j];\n',
'epsilon[1, j] = error[1, j];\n',
'for(i in 2:n){\n',
'// lagged error ma process\n',
'epsilon[i, j] = theta[j] * error[i-1, j];\n',
'// full ARMA process\n',
'trend[i, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
if(drift){ 'drift[j] * (i - 1) + '} else {NULL},
if(trend_model == 'AR1'){ 'ar1[j] * '} else {NULL},
'trend[i - 1, j] + ',
'epsilon[i, j] + error[i, j];\n',
Expand All @@ -628,7 +618,6 @@ add_MaCor = function(model_file,
paste0(model_file[insert_line],
'\nfor(j in 1:n_series){\n',
'trend[1, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
'error[1, j];\n',
'epsilon[1, j] = error[1, j];\n',
'epsilon[2, j] = theta[j] * error[1, j];\n',
Expand All @@ -641,7 +630,7 @@ add_MaCor = function(model_file,
'epsilon[i, j] = theta[j] * error[i-1, j];\n',
'// full ARMA process\n',
'trend[i, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
if(drift){ 'drift[j] * (i - 1) + '} else {NULL},
'ar1[j] * trend[i - 1, j] + ',
'ar2[j] * trend[i - 2, j] + ',
'epsilon[i, j] + error[i, j];\n',
Expand All @@ -662,7 +651,6 @@ add_MaCor = function(model_file,
paste0(model_file[insert_line],
'\nfor(j in 1:n_series){\n',
'trend[1, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
'error[1, j];\n',
'epsilon[1, j] = error[1, j];\n',
'epsilon[2, j] = theta[j] * error[1, j];\n',
Expand All @@ -672,7 +660,7 @@ add_MaCor = function(model_file,
'ar1[j] * trend[1, j] + ',
'epsilon[2, j] + error[2, j];\n',
'trend[3, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
if(drift){ 'drift[j] * 2 + '} else {NULL},
'ar1[j] * trend[2, j] + ',
'ar2[j] * trend[1, j] + ',
'epsilon[2, j] + error[2, j];\n',
Expand All @@ -681,7 +669,7 @@ add_MaCor = function(model_file,
'epsilon[i, j] = theta[j] * error[i-1, j];\n',
'// full ARMA process\n',
'trend[i, j] = ',
if(drift){ 'drift[j] + '} else {NULL},
if(drift){ 'drift[j] * (i - 1) + '} else {NULL},
'ar1[j] * trend[i - 1, j] + ',
'ar2[j] * trend[i - 2, j] + ',
'ar3[j] * trend[i - 3, j] + ',
Expand Down
8 changes: 4 additions & 4 deletions R/add_base_dgam_lines.R
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,12 @@ add_base_dgam_lines = function(use_lv, stan = FALSE, offset = FALSE){
}
for (j in 1:n_lv) {
LV_raw[3, j] ~ dnorm(drift[j] + ar1[j]*LV_raw[2, j] + ar2[j]*LV_raw[1, j], penalty[j])
LV_raw[3, j] ~ dnorm(drift[j]*2 + ar1[j]*LV_raw[2, j] + ar2[j]*LV_raw[1, j], penalty[j])
}
for (i in 4:n) {
for (j in 1:n_lv) {
LV_raw[i, j] ~ dnorm(drift[j] + ar1[j]*LV_raw[i - 1, j] +
LV_raw[i, j] ~ dnorm(drift[j]*(i - 1) + ar1[j]*LV_raw[i - 1, j] +
ar2[j]*LV_raw[i - 2, j] + ar3[j]*LV_raw[i - 3, j], penalty[j])
}
}
Expand Down Expand Up @@ -365,12 +365,12 @@ add_base_dgam_lines = function(use_lv, stan = FALSE, offset = FALSE){
}
for (s in 1:n_series) {
trend[3, s] ~ dnorm(drift[s] + ar1[s]*trend[2, s] + ar2[s]*trend[1, s], tau[s])
trend[3, s] ~ dnorm(drift[s]*2 + ar1[s]*trend[2, s] + ar2[s]*trend[1, s], tau[s])
}
for (i in 4:n) {
for (s in 1:n_series){
trend[i, s] ~ dnorm(drift[s] + ar1[s]*trend[i - 1, s] + ar2[s]*trend[i - 2, s] + ar3[s]*trend[i - 3, s], tau[s])
trend[i, s] ~ dnorm(drift[s]*(i - 1) + ar1[s]*trend[i - 1, s] + ar2[s]*trend[i - 2, s] + ar3[s]*trend[i - 3, s], tau[s])
}
}
Expand Down
Loading

0 comments on commit 5b9d09b

Please sign in to comment.