Introducation
dsHelper contains a number of client-side functions designed to simplify data manipulation and analysis using DataSHIELD. Functions are grouped in the following families:
- Descriptive functions
- Data manipulation functions
- Utility functions
- Functions for trajectory models
This vignette demonstrates the first three families of function. Functions to assist with trajectory/mixed effect analysis are described in a separate tutorial.
#install.packages("remotes")
#library(remotes)
#install_github("timcadman/ds-helper")
#install_github("datashield/DSI")
#install_github("datashield/dsBaseClient")
#install.packages("DSMolgenisArmadillo")
#install.packages("tidyverse")
library(dsHelper)
library(DSI)
library(dsBaseClient)
library(DSMolgenisArmadillo)
library(tidyverse)
Data: simulated data based on LifeCycle variables
To demonstrate these functions we will use remote simulated data for three cohorts: ALSPAC, BCG & BiB.
If you are unsure how to log in, please consult the DataSHIELD vignette: [link]
url <- "https://armadillo-demo.molgenis.net"
token <- armadillo.get_token(url)
builder <- DSI::newDSLoginBuilder()
builder$append(
server = "alspac",
url = url,
table = "trajectories/data/alspac",
token = token,
driver = "ArmadilloDriver",
profile = "xenon")
builder$append(
server = "bcg",
url = url,
table = "trajectories/data/bcg",
token = token,
driver = "ArmadilloDriver",
profile = "xenon")
builder$append(
server = "bib",
url = url,
table = "trajectories/data/bib",
token = token,
driver = "ArmadilloDriver",
profile = "xenon")
logindata <- builder$build()
conns <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "data")
ds.colnames("data")
## $alspac
## [1] "id" "age" "sex" "ethnicity" "father_socialclass"
## [6] "mother_education" "weight"
##
## $bcg
## [1] "id" "age" "sex" "ethnicity" "father_socialclass"
## [6] "mother_education" "weight"
##
## $bib
## [1] "id" "age" "sex" "ethnicity" "father_socialclass"
## [6] "mother_education" "weight"
Data manipulation functions
Rename variables with dh.renameVars()
dh.renameVars allows you to change the names of one or more variables within a dataframe. For example, we can rename the variables “id”, and “ethnicity” with simpler names:
dh.renameVars(
df = "data",
current_names = c("ethnicity", "father_socialclass"),
new_names = c("race", "paternal_class"))
ds.colnames("data")
## $alspac
## [1] "id" "age" "sex" "mother_education" "weight" "race"
## [7] "paternal_class"
##
## $bcg
## [1] "id" "age" "sex" "mother_education" "weight" "race"
## [7] "paternal_class"
##
## $bib
## [1] "id" "age" "sex" "mother_education" "weight" "race"
## [7] "paternal_class"
Removing columns with dh.dropCols()
dh.dropCols allows you to remove columns from a dataframe. The argument “type” allows you to specify whether to remove or to keep the provided variables. For example, we can remove the column “mat_ed”:
dh.dropCols(
df = "data",
vars = "mother_education",
type = "remove")
ds.colnames("data")
## $alspac
## [1] "id" "age" "sex" "weight" "race" "paternal_class"
##
## $bcg
## [1] "id" "age" "sex" "weight" "race" "paternal_class"
##
## $bib
## [1] "id" "age" "sex" "weight" "race" "paternal_class"
Alternatively, we can just to keep certain columns and remove everything else. In this example we keep the columns “sex”, “height_m” and “ivf”:
dh.dropCols(
df = "data",
vars = c("id", "age", "sex", "weight"),
type = "keep")
ds.colnames("data")
## $alspac
## [1] "id" "age" "sex" "weight"
##
## $bcg
## [1] "id" "age" "sex" "weight"
##
## $bib
## [1] "id" "age" "sex" "weight"
Creating strata of a variable with dh.makeStrata()
A common scenario is when you have repeat measurements of a variable, but want to create individual versions of that variable within different age bands.
For example, you may have a dataset with repeat measurments of height between ages 2-18. However, you want to create a new variable which is height between ages 4-6. This is quite a long process in datashield, as it involves creating a number of subsets. It is also necessary to deal with situations where a subject has >1 observation within the specified period.
In the example below, we create two variables for child height measured between (i) ages 4-6 and (ii) ages 7-10. Where children have more than one observation in either window, we opt to take the earliest measurement. This behaviour is controlled by the argument “mult_action”. You can also choose to take (i) the latest variable, or (ii) the variable closest to a particular time point. Finally, within each band we choose to take values >= to the lowest band, and < the highest band. This behaviour is controlled by the argument “band_action”. See ?dh.makeStrata for more information on the available arguments.
In this example it runs quite quickly, however if you are using many cohorts with large datasets it can take a considerable amount of time (30 - 60 min).
dh.makeStrata(
df = "data",
var_to_subset = "weight",
age_var = "age",
bands = c(4, 6, 7, 10),
mult_action = "earliest",
band_action = "ge_l",
id_var = "id",
new_obj = "height_data")
## Error in `left_join()`:
## ! Join columns in `x` must be present in the data.
## ✖ Problem with `cohort` and `suffix`.
ds.colnames("height_data")
## $alspac
## [1] "id" "tmp_obj"
##
## $bcg
## [1] "id" "tmp_obj"
##
## $bib
## [1] "id" "tmp_obj"
The created dataset contains 5 variables: the id variable, two variables giving the height value within the specified bands (height_.6, height_.10) and two variables giving the age of measurement for these height variables (age.6, age.10).
We can then use ds.merge to join this dataframe back with our main data:
ds.merge(
x.name = "data",
y.name = "height_data",
by.x = "id",
by.y = "id",
all.x = TRUE,
newobj = "data")
ds.colnames("data")
## $alspac
## [1] "id" "age" "sex" "weight" "tmp_obj"
##
## $bcg
## [1] "id" "age" "sex" "weight" "tmp_obj"
##
## $bib
## [1] "id" "age" "sex" "weight" "tmp_obj"
Transforming continuous variable to interquartile range using dh.makeIQR()
In some scenarios (e.g. when using an environmental exposures) we want to standardise a continuous variable by transforming it by its interquartile range. The formula is:
value(subject) / 75th percentile(sample) - 25th percentile(sample)
When using data from multiple cohorts there are two options for the
denominator: (i) create IQR in each cohort using the interquartile range
in that cohort, (ii) create IQR in each cohort by using the combined
interquartile range across all cohorts. This is controlled by the
argument type
.
In this example we transform child weight. The created variable will
have the suffix “iqr_c” if type
is “separate” and “iqr_p”
if type = “pooled”.
dh.makeIQR(
df = "data",
vars = "weight",
type = "split",
new_obj = "data")
ds.colnames("data")
## $alspac
## [1] "id" "age" "sex" "weight" "tmp_obj" "weight_iqr_s"
##
## $bcg
## [1] "id" "age" "sex" "weight" "tmp_obj" "weight_iqr_s"
##
## $bib
## [1] "id" "age" "sex" "weight" "tmp_obj" "weight_iqr_s"
ds.summary("data$weight_iqr_s")
## $alspac
## $alspac$class
## [1] "numeric"
##
## $alspac$length
## [1] 129681
##
## $alspac$`quantiles & mean`
## 5% 10% 25% 50% 75% 90% 95% Mean
## 0.4091894 0.4749404 0.8753985 1.9270502 4.0167522 5.8588743 6.8073844 2.6408378
##
##
## $bcg
## $bcg$class
## [1] "numeric"
##
## $bcg$length
## [1] 12724
##
## $bcg$`quantiles & mean`
## 5% 10% 25% 50% 75% 90% 95% Mean
## 0.4297604 0.4883779 0.6827643 1.2218283 1.6454341 1.9312762 2.0859876 1.2049523
##
##
## $bib
## $bib$class
## [1] "numeric"
##
## $bib$length
## [1] 68864
##
## $bib$`quantiles & mean`
## 5% 10% 25% 50% 75% 90% 95% Mean
## 0.3423285 0.3857788 0.4784658 0.7840827 1.4784658 1.9096193 2.1163471 0.9941187
Removing objects from workspace using dh.tidyEnv()
The DataSHIELD function ds.rm()
allows you to remove
single objects from your workspace. However, we may want to remove a
number of objects at once. Use the argument type
to choose
whether to keep or remove the variables listed in vars
.
Here we chose to keep “data” and remove everything else.
dh.tidyEnv(
obj = "data",
type = "keep")
ds.ls()
## $alspac
## $alspac$environment.searched
## [1] "R_GlobalEnv"
##
## $alspac$objects.found
## [1] "data"
##
##
## $bcg
## $bcg$environment.searched
## [1] "R_GlobalEnv"
##
## $bcg$objects.found
## [1] "data"
##
##
## $bib
## $bib$environment.searched
## [1] "R_GlobalEnv"
##
## $bib$objects.found
## [1] "data"
Identifying column indices using dh.findVarsIndex
There are some occasions when we need to do know what column a set of
variables is. For example, the function ds.dataFrameSubset takes an
input for the argument keep.cols
a vector column
positions.
Subsetting data frames by column number is highly susceptable to breaking (e.g if you change the order of steps in a script). This function allows you to identify the column numbers of a vector of column names, like so:
indices <- dh.findVarsIndex(
df = "data",
vars = c("sex", "age", "weight"))
indices
## $alspac
## [1] 2 3 4
##
## $bcg
## [1] 2 3 4
##
## $bib
## [1] 2 3 4
Describing data
Summarising data using dh.getStats()
The DataSHIELD functions ds.summary
and
ds.table
produce basic descriptive statistics. However,
they have a number of limitations: the output is not in a very useable
format, you can only specify one variable at a time, and they don’t
provide some information that we will likely need in manuscripts
(e.g. about missingness).
Here we describe multiple variables using dh.getStats():
stats <- dh.getStats(
df = "data",
vars = c("age", "sex", "weight")
)
stats
## $categorical
## # A tibble: 0 × 10
## # ℹ 10 variables: variable <chr>, cohort <chr>, category <chr>, value <dbl>, cohort_n <int>, valid_n <dbl>,
## # missing_n <dbl>, perc_valid <dbl>, perc_missing <dbl>, perc_total <dbl>
##
## $continuous
## # A tibble: 12 × 15
## variable cohort mean std.dev perc_5 perc_10 perc_25 perc_50 perc_75 perc_90 perc_95 valid_n cohort_n missing_n
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 age alspac 6.2 5.53 0 0.1 0.83 4.52 10.8 13.9 15.7 129681 129681 0
## 2 age bcg 2.01 1.67 0 0.12 0.5 1.52 3.51 4.53 4.99 12724 12724 0
## 3 age bib 1.48 1.74 0 0 0.08 0.71 2.11 4.72 4.98 68864 68864 0
## 4 sex alspac 0.49 0.5 0 0 0 0 1 1 1 129681 129681 0
## 5 sex bcg 0.48 0.5 0 0 0 0 1 1 1 12724 12724 0
## 6 sex bib 0.49 0.5 0 0 0 0 1 1 1 68864 68864 0
## 7 weight alspac 25.3 20.2 3.93 4.56 8.4 18.5 38.5 56.2 65.3 129681 129681 0
## 8 weight bcg 11.6 5.29 4.12 4.69 6.55 11.7 15.8 18.5 20.0 12724 12724 0
## 9 weight bib 9.54 5.81 3.28 3.7 4.59 7.52 14.2 18.3 20.3 68864 68864 0
## 10 age combined 4.41 5.01 0 0.07 0.57 3.1 7.55 10.4 11.6 211269 211269 0
## 11 sex combined 0.49 0.5 0 0 0 0 1 1 1 211269 211269 0
## 12 weight combined 19.4 17.9 3.73 4.29 7.05 14.5 29.2 41.6 47.9 211269 211269 0
## # ℹ 1 more variable: missing_perc <dbl>
The output is a list of two tibbles, corresponding to categorical and continuous variables. See the help file for a list of calculated figures and stats.
Extracting model coefficients using dh.lmTab
When we run simple linear regression models in DataSHIELD, the coefficients are returned within a nested list. It can be a bit tricky to manually extract these (e.g. to create a table or a plot). This function extracts the coefficients from linear models and outputs them in a tibble. It can also handle mixed-effect models and will also return summaries of random effects.
output <- ds.glm(formula = "weight~age", data = "data", family = "gaussian")
dh.lmTab(
model = output,
type = "glm_ipd",
direction = "wide",
ci_format = "separate")
## Error: Assertion on 'model' failed. function (msg)
## msgs <<- c(msgs, msg).
## Error: Assertion on 'model' failed. function ()
## msgs.
## Error: Assertion on 'model' failed. function ()
## length(msgs) == 0.
For manuscripts we may want to include confidence intervals in brackets after the point estimate. We can specify this with the argument “ci_format”:
dh.lmTab(
model = output,
type = "glm_ipd",
direction = "wide",
ci_format = "paste")
## Error: Assertion on 'model' failed. function (msg)
## msgs <<- c(msgs, msg).
## Error: Assertion on 'model' failed. function ()
## msgs.
## Error: Assertion on 'model' failed. function ()
## length(msgs) == 0.
Checking class of data using dh.classDiscrepancy()
In an ideal world all variables would have the same class in every study. However due to mistakes in harmonisation (or your scripts!) this may not be the case. The can cause problems because many DataSHIELD functions require the input variable(s) to have the same class in all studies.
Using dh.classDiscrepancy we can produce a tibble summarising the
class of variable(s) across multiple studies. If we leave the argument
vars
empty we check the class of all variables. The column
“discrepancy” summarises whether there are differences across
studies.
disc <- dh.classDiscrepancy(df = "data")
disc
## # A tibble: 6 × 5
## variable discrepancy alspac bcg bib
## <chr> <chr> <chr> <chr> <chr>
## 1 id no numeric numeric numeric
## 2 age no numeric numeric numeric
## 3 sex no numeric numeric numeric
## 4 weight no numeric numeric numeric
## 5 tmp_obj no numeric numeric numeric
## 6 weight_iqr_s no numeric numeric numeric
Checking non-missing data using dh.anyData()
When we perform analyses with multiple cohorts, we may want to use the same set of covariates in all analyses. We can use dh.anyData() to check which cohortsh have at least some data on given variables.
available <- dh.anyData(
df = "data",
vars = c("age", "sex", "weight"))
available
## # A tibble: 3 × 4
## variable alspac bcg bib
## <chr> <lgl> <lgl> <lgl>
## 1 age TRUE TRUE TRUE
## 2 sex TRUE TRUE TRUE
## 3 weight TRUE TRUE TRUE
Creating a dataset for analysis using dh.defineCases()
Before starting analysis we often want to restrict the dataset to subjects meeting certain criteria. In the first example, we create a vector indicating whether each subject has complete data on the set of variables age, sex and weight:
dh.defineCases(
df = "data",
vars = c("age", "sex", "weight"),
type = "all",
new_obj = "data_on_all_vars")
cases_all <- ds.table("data_on_all_vars")$output.list$TABLE_rvar.by.study_counts
cases_all
## study
## data_on_all_vars alspac bcg bib
## 1 129681 12724 68864
## NA 0 0 0
The data we have here is not the best to illustrate this function, as there is no missing data.
We can also check whether subjects have available data on any of a set of variables:
dh.defineCases(
df = "data",
vars = c("age", "sex", "weight"),
type = "any",
new_obj = "data_on_any_vars")
cases_any <- ds.table("data_on_any_vars")$output.list$TABLE_rvar.by.study_counts
cases_any
## study
## data_on_any_vars alspac bcg bib
## 1 129681 12724 68864
## NA 0 0 0
Again, we can’t see the differences because all subjects have data on all variables. However, lets assume that we want to create an subset of our data restricted to participants with data on at least one of these variables. We can then use ds.dataFrameSubset in conjuncture with the vector we created:
ds.dataFrameSubset(
df.name = "data",
V1.name = "data_on_all_vars",
V2.name = "1",
Boolean.operator = "==",
newobj = "complete_df")
## $`dimensions of data in alspac`
## [1] 129681 6
##
## $`dimensions of data in bcg`
## [1] 12724 6
##
## $`dimensions of data in bib`
## [1] 68864 6
##
## $`dimensions of data in combined studies`
## [1] 211269 6
##
## $`dimensions of complete_df in alspac`
## [1] 129681 6
##
## $`dimensions of complete_df in bcg`
## [1] 12724 6
##
## $`dimensions of complete_df in bib`
## [1] 68864 6
##
## $`dimensions of complete_df in combined studies`
## [1] 211269 6
Miscellaneous functions
Enabling auto-complete functionality within R Studio.
When using R studio with native R, auto-complete suggestions will appear for variables within a data frame. However, by default these won’t appear for variables within a serverside data frame.
We can get round this by creating a local object with the same structure as the remote object. Once you have run this function, autocomplete options for the data frame “data” should now be available.
dh.localProxy(df = "data", conns = conns)
Manually pooling estimates by meta-analysis
Most of the time the meta-analysis functions in DataSHIELD (e.g. ds.glmSLMA) will be sufficient. However, you may sometimes need additional flexibility with meta-analysis. For example, currently ds.glmSLMA doesn’t return heterogeneity statistics.
This functions takes vectors of coefficients and standard errors from multiple cohorts and meta-analyses them.
First we fit a model in different cohorts and extract the coefficients:
output <- ds.glmSLMA(
formula = "weight~age",
dataName = "data",
family = "gaussian")
Now we can use this object and to the meta-analysis manually:
meta_analysed <- dh.metaManual(
model = output,
method = "ML")
The output consists of a list with two elements. The first element (“model”) is a list with the output from metafor. The length will be the number of variables meta-analysed:
str(meta_analysed$model)
## List of 2
## $ (Intercept):List of 74
## ..$ b : num [1, 1] 4.91
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr "intrcpt"
## .. .. ..$ : NULL
## ..$ beta : num [1, 1] 4.91
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr "intrcpt"
## .. .. ..$ : NULL
## ..$ se : num 0.415
## ..$ zval : num 11.8
## ..$ pval : num 3.03e-32
## ..$ ci.lb : num 4.09
## ..$ ci.ub : num 5.72
## ..$ vb : num [1, 1] 0.172
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr "intrcpt"
## .. .. ..$ : chr "intrcpt"
## ..$ tau2 : num 0.516
## ..$ se.tau2 : num 0.422
## ..$ tau2.fix : logi FALSE
## ..$ tau2.f : num 0.516
## ..$ I2 : num 99.9
## ..$ H2 : num 994
## ..$ R2 : NULL
## ..$ vt : num 0.000519
## ..$ QE : num 1753
## ..$ QEp : num 0
## ..$ QM : num 140
## ..$ QMdf : int [1:2] 1 NA
## ..$ QMp : num 3.03e-32
## ..$ k : int 3
## ..$ k.f : int 3
## ..$ k.eff : int 3
## ..$ k.all : int 3
## ..$ p : int 1
## ..$ p.eff : int 1
## ..$ parms : num 2
## ..$ int.only : logi TRUE
## ..$ int.incl : logi TRUE
## ..$ intercept : logi TRUE
## ..$ allvipos : logi TRUE
## ..$ coef.na : Named logi FALSE
## .. ..- attr(*, "names")= chr "X"
## ..$ yi : Named num [1:3] 4.02 5.78 4.92
## .. ..- attr(*, "names")= chr [1:3] "betas study 1" "betas study 2" "betas study 3"
## .. ..- attr(*, "measure")= chr "GEN"
## .. ..- attr(*, "slab")= int [1:3] 1 2 3
## ..$ vi : Named num [1:3] 0.000819 0.000964 0.000108
## .. ..- attr(*, "names")= chr [1:3] "ses study 1" "ses study 2" "ses study 3"
## ..$ X : num [1:3, 1] 1 1 1
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : NULL
## .. .. ..$ : chr "intrcpt"
## ..$ weights : NULL
## ..$ yi.f : Named num [1:3] 4.02 5.78 4.92
## .. ..- attr(*, "names")= chr [1:3] "betas study 1" "betas study 2" "betas study 3"
## .. ..- attr(*, "measure")= chr "GEN"
## .. ..- attr(*, "slab")= int [1:3] 1 2 3
## ..$ vi.f : Named num [1:3] 0.000819 0.000964 0.000108
## .. ..- attr(*, "names")= chr [1:3] "ses study 1" "ses study 2" "ses study 3"
## ..$ X.f : num [1:3, 1] 1 1 1
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : NULL
## .. .. ..$ : chr "intrcpt"
## ..$ weights.f : NULL
## ..$ M : num [1:3, 1:3] 0.517 0 0 0 0.517 ...
## ..$ outdat.f :List of 8
## .. ..$ ai : num NA
## .. ..$ bi : num NA
## .. ..$ ci : num NA
## .. ..$ di : num NA
## .. ..$ x1i: num NA
## .. ..$ x2i: num NA
## .. ..$ t1i: num NA
## .. ..$ t2i: num NA
## ..$ ni : NULL
## ..$ ni.f : NULL
## ..$ ids : int [1:3] 1 2 3
## ..$ not.na : Named logi [1:3] TRUE TRUE TRUE
## .. ..- attr(*, "names")= chr [1:3] "betas study 1" "betas study 2" "betas study 3"
## ..$ subset : NULL
## ..$ slab : int [1:3] 1 2 3
## ..$ slab.null : logi TRUE
## ..$ measure : chr "GEN"
## ..$ method : chr "ML"
## ..$ model : chr "rma.uni"
## ..$ weighted : logi TRUE
## ..$ test : chr "z"
## ..$ dfs : int NA
## ..$ ddf : int NA
## ..$ s2w : num 1
## ..$ btt : int 1
## ..$ m : int 1
## ..$ digits : Named num [1:9] 4 4 4 4 4 4 4 4 4
## .. ..- attr(*, "names")= chr [1:9] "est" "se" "test" "pval" ...
## ..$ level : num 0.05
## ..$ control : list()
## ..$ verbose : logi FALSE
## ..$ add : num 0.5
## ..$ to : chr "only0"
## ..$ drop00 : logi FALSE
## ..$ fit.stats :'data.frame': 5 obs. of 2 variables:
## .. ..$ ML : num [1:5] -3.27 24.21 10.53 8.73 22.53
## .. ..$ REML: num [1:5] -2.68 5.36 9.36 6.74 21.36
## ..$ data :<environment: 0x139378300>
## ..$ formula.yi : NULL
## ..$ formula.mods: NULL
## ..$ version :Classes 'package_version', 'numeric_version' hidden list of 1
## .. ..$ : int [1:3] 4 2 0
## ..$ call : language rma(yi = model$betamatrix.valid[x, ], sei = model$sematrix.valid[x, ], method = "ML")
## ..$ time : num 0.003
## ..- attr(*, "class")= chr [1:2] "rma.uni" "rma"
## $ age :List of 74
## ..$ b : num [1, 1] 3.14
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr "intrcpt"
## .. .. ..$ : NULL
## ..$ beta : num [1, 1] 3.14
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr "intrcpt"
## .. .. ..$ : NULL
## ..$ se : num 0.133
## ..$ zval : num 23.6
## ..$ pval : num 6.46e-123
## ..$ ci.lb : num 2.88
## ..$ ci.ub : num 3.41
## ..$ vb : num [1, 1] 0.0178
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr "intrcpt"
## .. .. ..$ : chr "intrcpt"
## ..$ tau2 : num 0.0533
## ..$ se.tau2 : num 0.0435
## ..$ tau2.fix : logi FALSE
## ..$ tau2.f : num 0.0533
## ..$ I2 : num 99.9
## ..$ H2 : num 1915
## ..$ R2 : NULL
## ..$ vt : num 2.78e-05
## ..$ QE : num 4454
## ..$ QEp : num 0
## ..$ QM : num 556
## ..$ QMdf : int [1:2] 1 NA
## ..$ QMp : num 6.46e-123
## ..$ k : int 3
## ..$ k.f : int 3
## ..$ k.eff : int 3
## ..$ k.all : int 3
## ..$ p : int 1
## ..$ p.eff : int 1
## ..$ parms : num 2
## ..$ int.only : logi TRUE
## ..$ int.incl : logi TRUE
## ..$ intercept : logi TRUE
## ..$ allvipos : logi TRUE
## ..$ coef.na : Named logi FALSE
## .. ..- attr(*, "names")= chr "X"
## ..$ yi : Named num [1:3] 3.44 2.87 3.12
## .. ..- attr(*, "names")= chr [1:3] "betas study 1" "betas study 2" "betas study 3"
## .. ..- attr(*, "measure")= chr "GEN"
## .. ..- attr(*, "slab")= int [1:3] 1 2 3
## ..$ vi : Named num [1:3] 1.19e-05 1.41e-04 2.07e-05
## .. ..- attr(*, "names")= chr [1:3] "ses study 1" "ses study 2" "ses study 3"
## ..$ X : num [1:3, 1] 1 1 1
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : NULL
## .. .. ..$ : chr "intrcpt"
## ..$ weights : NULL
## ..$ yi.f : Named num [1:3] 3.44 2.87 3.12
## .. ..- attr(*, "names")= chr [1:3] "betas study 1" "betas study 2" "betas study 3"
## .. ..- attr(*, "measure")= chr "GEN"
## .. ..- attr(*, "slab")= int [1:3] 1 2 3
## ..$ vi.f : Named num [1:3] 1.19e-05 1.41e-04 2.07e-05
## .. ..- attr(*, "names")= chr [1:3] "ses study 1" "ses study 2" "ses study 3"
## ..$ X.f : num [1:3, 1] 1 1 1
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : NULL
## .. .. ..$ : chr "intrcpt"
## ..$ weights.f : NULL
## ..$ M : num [1:3, 1:3] 0.0533 0 0 0 0.0534 ...
## ..$ outdat.f :List of 8
## .. ..$ ai : num NA
## .. ..$ bi : num NA
## .. ..$ ci : num NA
## .. ..$ di : num NA
## .. ..$ x1i: num NA
## .. ..$ x2i: num NA
## .. ..$ t1i: num NA
## .. ..$ t2i: num NA
## ..$ ni : NULL
## ..$ ni.f : NULL
## ..$ ids : int [1:3] 1 2 3
## ..$ not.na : Named logi [1:3] TRUE TRUE TRUE
## .. ..- attr(*, "names")= chr [1:3] "betas study 1" "betas study 2" "betas study 3"
## ..$ subset : NULL
## ..$ slab : int [1:3] 1 2 3
## ..$ slab.null : logi TRUE
## ..$ measure : chr "GEN"
## ..$ method : chr "ML"
## ..$ model : chr "rma.uni"
## ..$ weighted : logi TRUE
## ..$ test : chr "z"
## ..$ dfs : int NA
## ..$ ddf : int NA
## ..$ s2w : num 1
## ..$ btt : int 1
## ..$ m : int 1
## ..$ digits : Named num [1:9] 4 4 4 4 4 4 4 4 4
## .. ..- attr(*, "names")= chr [1:9] "est" "se" "test" "pval" ...
## ..$ level : num 0.05
## ..$ control : list()
## ..$ verbose : logi FALSE
## ..$ add : num 0.5
## ..$ to : chr "only0"
## ..$ drop00 : logi FALSE
## ..$ fit.stats :'data.frame': 5 obs. of 2 variables:
## .. ..$ ML : num [1:5] 0.14 25.2 3.72 1.92 15.72
## .. ..$ REML: num [1:5] -0.407 0.814 4.814 2.201 16.814
## ..$ data :<environment: 0x12971ce00>
## ..$ formula.yi : NULL
## ..$ formula.mods: NULL
## ..$ version :Classes 'package_version', 'numeric_version' hidden list of 1
## .. ..$ : int [1:3] 4 2 0
## ..$ call : language rma(yi = model$betamatrix.valid[x, ], sei = model$sematrix.valid[x, ], method = "ML")
## ..$ time : num 0.003
## ..- attr(*, "class")= chr [1:2] "rma.uni" "rma"
The second element (“coefficients”) is a summary table:
meta_analysed$coefs
## # A tibble: 2 × 3
## term coef se
## <chr> <dbl> <dbl>
## 1 (Intercept) 4.91 0.415
## 2 age 3.14 0.133
Finish by logging out of the demo server
datashield.logout(conns)