[R-meta] Extracting meta regression elements automatically

d@@iei@i@gucci@rdi m@iii@g oii gm@ii@com d@@iei@i@gucci@rdi m@iii@g oii gm@ii@com
Fri Jun 23 00:45:12 CEST 2023


Hi all,

 

I'm analysing data for a 3-level meta-analysis with metafor in which I'd
like to explore moderation effects for 6 outcome variables across 11
different moderators variables. I'd like to extract key elements of the
results of these moderator analyses automatically rather than manually,
given the large quantity of output. 

 

First, I've created the following function to execute the meta-regression
analyses:

 

run_meta.moderator <- function(df_list, df_names, moderators, scale_mods =
NULL) {

  output_list <- list()

  

  for (i in seq_along(df_list)) {

    df <- df_list[[i]]

    df_name <- df_names[i]

    moderator_results <- list()

    

    for (j in seq_along(moderators)) {

      moderator <- moderators[[j]]

      

      # Check the number of levels in the moderator variable

      if (length(unique(df[[moderator]])) <= 1) {

        # Skip the moderator if there is only one level

        next

      }

      

      # Scale continuous moderators if specified

      if (moderator %in% scale_mods) {

        df[[moderator]] <- scale(df[[moderator]])

      }

      # Perform the meta-analytic computations for the current moderator

      # Wrap the computations in a tryCatch block to handle convergence
issues

      tryCatch({

        anova_result <- rma.mv(yi, vi,

                               data = df,

                               level = 95,

                               method = "REML",

                               tdist = TRUE,

                               mods = as.formula(paste("~", moderator)),

                               random = ~ 1 | study_id/esid,

                               control=list(rel.tol=1e-8))

        

        mods_result <- rma.mv(yi, vi,

                              data = df,

                              level = 95,

                              method = "REML",

                              tdist = TRUE,

                              mods = as.formula(paste("~", moderator, "-
1")),

                              random = ~ 1 | study_id/esid,

                              control=list(rel.tol=1e-8))

        

        moderator_results[[moderator]] <- list(anova_result = anova_result,

                                               mods_result = mods_result)

      }, error = function(e) {

        # Print a warning message if convergence fails for the current
moderator

        warning(paste("Convergence failed for moderator:", moderator, "in
data frame:", df_name))

      })

      

    }

    

    # Assign the moderator results for the current data frame to the output
list

    output_list[[df_name]] <- moderator_results

  }

  

  return(output_list)

}

 

# run the function for each moderator individually

df_list <- list(df1 = df.psychosocial.protective, 

                df2 = df.psychosocial.risk,

                df3 = df.beh_inadvertent.protective,

                df4 = df.beh_inadvertent.risk,

                df5 = df.use.protective,

                df6 = df.use.risk)

df_names <- c("df.psychosocial.protective", 

              "df.psychosocial.risk",

              "df.beh_inadvertent.protective",

              "df.beh_inadvertent.risk",

              "df.use.protective",

              "df.use.risk")

 

moderators <- list("data_adjusted", "data_type", "study_design",
"participant_category",

                   "sport_type", "sport_level", "gender", "substance_type",
"stage_1", "stage_2", "age")

scale_mods <- c("age")  # Specify the moderators to be scaled

results.meta.moderator <- run_meta.moderator(df_list, df_names, moderators,
scale_mods)

 

This function executes successfully. 

 

Second, I'd like to extract the following elements of the output for
results.meta.moderator to an excel file (for easy manipulation, formatting,
etc):

1.	From the 'Test of Moderators' section of 'anova_result':   

a.	F value, 
b.	df1 and df2, 
c.	p-val

2.	From the 'Model Results' section of 'mods_result' for each level of
each moderator:

a.	estimate
b.	se
c.	ci.lb
d.	ci.ub 

 

Here is where I was hoping you could help, as I encounter issues when
attempting to extract the information from 'anova_result' and 'mods_result'.
For example, here is a function which I thought could work but doesn't
(e.g., "Error in anova_result$QM$df1 : $ operator is invalid for atomic
vectors"):

 

extract_moderator_results <- function(results) {

  extracted_results <- list()

  

  for (df_name in names(results)) {

    moderator_results <- results[[df_name]]

    extracted_df <- data.frame()

    

    for (moderator_name in names(moderator_results)) {

      anova_result <- moderator_results[[moderator_name]]$anova_result

      mods_result <- moderator_results[[moderator_name]]$mods_result

      

      # Extract elements from 'Test of Moderators' section

      anova_df <- data.frame(

        F_value = anova_result$QM,

        df1 <- anova_result$QM$df1,

        df2 <- anova_result$QM$df2,

        p_value = anova_result$QMp

      )

      

      # Extract elements from 'Model Results' section for each level of the
moderator

      mods_df <- data.frame(

        level = levels(mods_result$model)[[2]],

        estimate = coef(mods_result)$estimate,

        se = coef(mods_result)$se,

        ci_lb = confint(mods_result)[, "ci.lb"],

        ci_ub = confint(mods_result)[, "ci.ub"]

      )

      

      # Add the moderator name as a column to both data frames

      anova_df$moderator = moderator_name

      mods_df$moderator = moderator_name

      

      # Append the data frames to the extracted results data frame

      extracted_df <- rbind(extracted_df, anova_df, mods_df)

    }

    

    # Assign the extracted results for the current data frame to the output
list

    extracted_results[[df_name]] <- extracted_df

  }

  

  return(extracted_results)

}

 

 

# Load the 'writexl' package if not already installed

if (!requireNamespace("writexl", quietly = TRUE)) {

  install.packages("writexl")

}

library(writexl)

 

# Extract the moderator results

extracted_results <- extract_moderator_results(results.meta.moderator)

 

# Save the extracted results to an Excel file

output_file <- "moderator_results.xlsx"

for (df_name in names(extracted_results)) {

  write_xlsx(extracted_results[[df_name]], path = output_file, sheet =
df_name, append = TRUE)

}

 

Welcome your advice please. For context, I'm a novice when it comes to
writing functions, so I suspect I've overlooked something simple or am
likely out of my depth here! Many thanks in advance. 

 

Cheers,

Daniel

 


	[[alternative HTML version deleted]]



More information about the R-sig-meta-analysis mailing list