The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

Introduction

The purpose of the metagam package is to meta-analyze generalized additive models (GAMs), including generalized additive mixed models (GAMMs). The main application we have in mind is the case in which researchers at different locations have the same type of data, but are not allowed to share the rawdata. The metagam package offers an opportunity to gain statistical power by fitting similar GAMs to the data in each location, removing individual participant data from the model objects such that they can be shared to a common location, and finally obtaining a meta-analytic GAM fit from the individual models. The methodology is described in detail in Sorensen et al. (2021).

The reason the methods in metagam are needed, is that current meta-analytic approaches mainly focusing on combining model parameters, e.g., regression coefficients or correlations. This approach works well in many cases, but there are many important problems for which it is impractical or impossible to use parametric models. GAMs offer a flexible way to fit various functional forms Wood (2017). Some current meta-analytic approaches to GAMs have required exactly the same basis functions and knot placement to be used in the model fitted to each dataset, but this is in general suboptimal and when the range of some explanatory variable differs between cohorts, it may often lead to models that are not identifiable. metagam hence instead combines the model fits (predictions) over some grid specified by the user.

Basic Usage Example

Assume some data of interest are located in three different cohorts. In order to increase statistical power and hence be more able to detect relationships in the data, we would ideally fit a GAM to all three datasets combined, using a model on the form y ~ s(x0) + s(x1) + s(x2), where y is an outcome of interest and x1 and x2 are explanatory variables. The smooth functions s() allow the outcome to vary nonlinearly as a function of each explanatory variable. When all three datasets are not available in a single location, we cannot fit a GAM using this mega-analytic approach. The metagam package provides a flexible solution to this problem, which here will be illustrated.

We start by simulation three datasets using the gamSim() function from mgcv.

library(metagam)
library(mgcv)
## simulate three datasets
set.seed(123)
datasets <- lapply(1:3, function(x) gamSim(scale = 3, verbose = FALSE))

In each data location, we assume a GAM with the generic form y~s(x0)+s(x1)+s(x2) is fit to the data. Notably, model parameters like knot locations, number of basis functions, and smoothing method does not need to be identical in each separate fit. Instead, the parameters can be optimized independently to fit the data in each location.

Here is an example:

## Data location 1
fit1 <- gam(y ~ s(x0, k = 8, bs = "cr") + s(x1, bs = "cr") + s(x2, bs = "cr"), 
            data = datasets[[1]])

## Data location 2, use P-splines for the first and third term
fit2 <- gam(y ~ s(x0, bs = "ps") + s(x1, k = 20, bs = "cr") + s(x2, bs = "bs"), 
            data = datasets[[2]])

## Data location 3, use maximum likelihood for smoothing
fit3 <- gam(y ~ s(x0, bs = "cr") + s(x1, bs = "cr") + s(x2, bs = "cr"), 
            data = datasets[[3]], method = "ML")

The gam objects fit1, fit2, and fit3 contain individual participant data in various forms, and hence there are many cases in which these should not be shared. The function strip_rawdata() from metagam removes all such rawdata. We here illustrate how this function can be applied at each data location in order to obtain a model fit that can be shared.

## Data location 1
fit_no_raw1 <- strip_rawdata(fit1)

## Data location 2
fit_no_raw2 <- strip_rawdata(fit2)

## Data location 3
fit_no_raw3 <- strip_rawdata(fit3)

Now assume that the objects fit_no_raw1, fit_no_raw2, and fit_no_raw3 have been gathered in a single location. First, we can inspect each of the objects.

summary(fit_no_raw1)
#> GAM stripped for individual participant data with strip_rawdata().
#> For meta-analysis of smooth terms, use the following identifiers: s(x0), s(x1), s(x2).
#> 
#> Original output for gam object:
#> 
#> Family: gaussian 
#> Link function: identity 
#> 
#> Formula:
#> y ~ s(x0, k = 8, bs = "cr") + s(x1, bs = "cr") + s(x2, bs = "cr")
#> 
#> Parametric coefficients:
#>             Estimate Std. Error t value Pr(>|t|)    
#> (Intercept)   8.0156     0.1553   51.62   <2e-16 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Approximate significance of smooth terms:
#>         edf Ref.df      F  p-value    
#> s(x0) 3.746  4.565  5.782 9.26e-05 ***
#> s(x1) 2.466  3.070 49.388  < 2e-16 ***
#> s(x2) 7.493  8.416 33.457  < 2e-16 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> R-sq.(adj) =  0.537   Deviance explained = 55.3%
#> GCV = 10.013  Scale est. = 9.645     n = 400

We can now perform a meta-analysis of these fits using the metagam() function. We gather them in a list:

models <- list(cohort1 = fit_no_raw1, 
               cohort2 = fit_no_raw2, 
               cohort3 = fit_no_raw3)

It is typically most convenient to analyze a single smooth term at a time. We start with the term s(x0), and set grid_size=100 to get 100 equally spaced values of x0 within the range of values encountered in the three model fits. The summary method prints out some information as well as meta-analytic p-values for the term.

metafit <- metagam(models, terms = "s(x0)")
summary(metafit)
#> Meta-analysis of GAMs from  cohorts, using method FE.
#> 
#> Smooth terms analyzed: s(x0).

The default plotting function shows the fits on the separate datasets together with the meta-analytic fit.

plot(metafit)

We can add confidence intervals. The \(\alpha\) is set in the call to metagam, defaulting to 0.05. Since a ggplot object is returned, we can also edit its appearance.

library(ggplot2)
plot(metafit, ci = "pointwise", only_meta = TRUE) + 
  theme_bw() + 
  theme(panel.grid = element_blank())

Dominance plots and heterogeneity plots can also be created. These are described in separate vignettes.

References

Sorensen, Oystein, Andreas M. Brandmaier, Didac Macia, Klaus Ebmeier, Paolo Ghisletta, Rogier A. Kievit, Athanasia M. Mowinckel, Kristine B. Walhovd, Rene Westerhausen, and Anders Fjell. 2021. “Meta-Analysis of Generalized Additive Models in Neuroimaging Studies.” NeuroImage 224 (January): 117416. https://doi.org/10.1016/j.neuroimage.2020.117416.
Wood, S. N. 2017. Generalized Additive Models: An Introduction with r. 2nd ed. Chapman; Hall/CRC.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.