---
title: "Meta-analysis with R package 'psychmeta'"
output: 
  rmdformats::robobook:
  html_document: default
  word_document: default
editor_options:
  chunk_output_type: console
---
Author: Yuwei Li  
Version date: 8/20/2022

This tutorial was originally written to support Dr. James Dillard's graduate-level meta-analysis course in Fall 2021. The tutorial uses the Hunter-Schmidt approach to meta-analysis (individual correction of measurement errors), as well as example data from Schmidt & Hunter's book (2014) to illustrate the procedures of running and plotting meta-analysis on a bivariate correlation, as well as moderation analysis. 

# Prep work

## A handy R shortcut
Keys|Function
----|----
Ctrl/Cmd + Enter|run highlighted/selected code or current line

## Setting up packages

+  You only need to install packages once. To run the first line, remove the #, then click the green triangle on top of the code block. The library() function loads packages to the environment for you to use, and needs to be repeated if you reboot your computer/R/RStudio. 

+  You can find out information about packages and functions using the help tab in the lower-right panel, or look for their documentations on *[cran](https://cran.r-project.org)*. 
```{r, message=FALSE}
#install.packages("metafor","psychmeta","dplyr","readxl")
library(metafor)
library(psychmeta)
library(dplyr)
library(devtools)
library(readxl) 
```

## Reading the dataset into the environment

+ If your files are stored in the same directory as your *.rmd file, you can locate them using just quotes "". Otherwise, you can specify the file path based on your OS. 

+ read_xlsx() reads excel spreadsheets. The "1" below identifies the worksheet to be read in an *.xlsx file, and is optional. Here, head() shows the first 6 lines read from the data file. 
```{r}
read_xlsx("ExampleData.xlsx",1)->ES
head(ES)
```
+ Arrows (-> & <-) are used to define/create objects in R, analogous to "=" in some other programing languages. The following line creates a "dataframe object" named "ES," and it shows up in the upper-right environment tab. 
+ variable.names() gives you a list of column names of a data frame/matrix object. This will come in handy. 
```{r}
variable.names(ES)
```

# Running meta-analysis

+ In the psychmeta package, ma_r and ma_d are the generic meta-analysis function for r and d values, respectively. These functions create an object when run, so you should save the object using arrows (see above).
+ Once you run the ma_r() function below, you have your meta-analysis results stored in the object called "meta.object."
+ If your column/variable names contain illegal characters like space, use backtick ` to wrap around your variable name in the function.  
```{r, message=FALSE, results = FALSE}
ma_r(rxyi = corr,
     n = Nr,
     sample_id = `Study No.`,
     ma_method = "ic", #individual corrections
     rxx = Rxx, correct_rxx = TRUE, 
     ryy = Ryy, correct_ryy = TRUE,
     data = ES)->meta.object
```
+ We can view the results of the meta-analysis using individually corrected effect sizes by calling out elements in meta.object. \$ extracts parts of an object (analogous to /slashes in file paths). Available elements will pop up as you type \$ to the end of an object. 
+ Here, we can examine the results table with both measurement errors in x & y corrected. 

```{r}
meta.object$meta_tables$`analysis_id: 1`$individual_correction$true_score
```
+ Comparing results between correcting measurement error for zero, one, and two variables: 
```{r, echo=FALSE}
#this block shows the comparison of barebones and corrected results
#you can skip this code block 
meta.object$meta_tables$`analysis_id: 1`$barebones->bare
rbind(
      meta.object$meta_tables$`analysis_id: 1`$individual_correction$validity_generalization_x,
      meta.object$meta_tables$`analysis_id: 1`$individual_correction$validity_generalization_y,
      meta.object$meta_tables$`analysis_id: 1`$individual_correction$true_score)->adjusted
round(rbind(
  data.frame(c(bare, sapply(setdiff(names(adjusted), names(bare)), function(x) NA))),
  data.frame(c(adjusted, sapply(setdiff(names(bare), names(adjusted)), function(x) NA)))
),3)->compiled.table
rownames(compiled.table)<-c("barebones","corrected for x", "corrected for y", "corrected both")
compiled.table

```


## Getting heterogeneity information and plots

+ By default, ma_r and ma_d do not contain heterogeneity statistics or plots. You can run the lines below to add those information to meta.object. Now, you can call out desired information the same way you accessed the results table. 
```{r, message=FALSE, results = FALSE}
heterogeneity(meta.object)->meta.object
plot_forest(meta.object)->meta.object
plot_funnel(meta.object)->meta.object
```
+ Heterogeneity statistics
```{r}
meta.object$heterogeneity$`analysis id: 1`$individual_correction$true_score
```


+ Forest plot
```{r}
meta.object$forest$`analysis id: 1`$unmoderated$individual_correction$ts
```
  

+ Funnel plot 
```{r}
meta.object$funnel$`analysis id: 1`$individual_correction$true_score
```



# Moderation Analysis
+ Moderation analysis requires specification of three more settings -- name of the moderator variable, whether the moderator is categorical, and the type of moderation analysis (none, simple, or hierarchical). The object generated will have more sets of results, and they will represent the overall meta-analysis, and then meta-analyses at different levels of the moderator variable. 
```{r, message=FALSE, results = FALSE}
ma_r(rxyi = corr,
     n = Nr,
     sample_id = `Study No.`,
     ma_method = "ic", #individual corrections
     rxx = Rxx, correct_rxx = TRUE, 
     ryy = Ryy, correct_ryy = TRUE,
     moderators = Moderator,
     cat_moderators = TRUE,
     moderator_type = "simple",
     data = ES)->meta.object2
```
+ We can add heterogeneity and plots to the object like we did with the unmoderated model. 

```{r, results = FALSE}
heterogeneity(meta.object2)->meta.object2
plot_forest(meta.object2)->meta.object2
plot_funnel(meta.object2)->meta.object2

```
+ Calling out "Moderator" within the object give you the identifiers of multiple analyses in this object. Here, we take a look at the unmoderated and moderated effects. 

```{r}

meta.object2$Moderator

rbind(meta.object2$meta_tables$`analysis_id: 1`$individual_correction$true_score,
      meta.object2$meta_tables$`analysis_id: 2`$individual_correction$true_score,
      meta.object2$meta_tables$`analysis_id: 3`$individual_correction$true_score)
```
\newpage  

+ Heterogeneity (not shown in the knitted file, runnable in rmd)
```{r, results = FALSE}
meta.object2$heterogeneity
```

+ Forest plot with moderation

```{r}
meta.object2$forest$`analysis id: 1`$moderated$individual_correction$ts
```

+ Note: Funnel plots are produced for individual analyses in psychmeta and do not show moderation. 

-----
### Additional Information

I created this tutorial with a system environment and versions of R and packages that might be different from yours. If R reports errors when you attempt to run this tutorial, running the code chunk below and comparing your output and the tutorial posted on the website may be helpful. 
  
```{r}
session_info(pkgs = c("attached"))

citation("psychmeta")
```


