Skip to contents

Introduction

The jforester function provides comprehensive forest plot visualization capabilities for meta-analyses, systematic reviews, and clinical trial results. It creates publication-ready forest plots that display point estimates with confidence intervals in a professional format suitable for academic publications.

Forest plots are essential tools in evidence-based medicine for visualizing the results of multiple studies or subgroup analyses. They allow researchers to:

  • Display effect sizes with confidence intervals across multiple studies
  • Visualize heterogeneity between studies
  • Present summary statistics and meta-analysis results
  • Compare subgroups or treatment effects
  • Communicate statistical findings effectively

Basic Forest Plot Creation

Simple Meta-Analysis Forest Plot

Let’s start with a basic forest plot using meta-analysis data with odds ratios:

# Load meta-analysis data
data(jforester_meta_analysis_data, package = "ClinicoPath")

# Display the first few rows of our dataset
head(jforester_meta_analysis_data)
# Create a basic forest plot
basic_forest <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  plot_title = "Meta-Analysis of Treatment Effectiveness",
  x_axis_label = "Odds Ratio (95% CI)"
)

# The plot will be displayed in jamovi interface

Understanding the Components

The forest plot displays several key components:

  • Study labels: Names or identifiers for each study (left side)
  • Point estimates: Central points representing effect sizes
  • Confidence intervals: Horizontal lines showing uncertainty
  • Reference line: Vertical line indicating “no effect” (typically 1 for ratios)
  • Scale: X-axis showing the range of effect sizes

Different Effect Types

Odds Ratios

Odds ratios are commonly used in case-control studies and logistic regression:

# Meta-analysis with odds ratios
or_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  plot_title = "Treatment Effect: Odds Ratios",
  x_axis_label = "Odds Ratio",
  reference_line = 1.0
)

Risk Ratios

Risk ratios are used in cohort studies and clinical trials:

# Load cardiovascular risk ratio data
data(jforester_cardio_rr_data, package = "ClinicoPath")

# Create risk ratio forest plot
rr_plot <- jforester(
  data = jforester_cardio_rr_data,
  study_labels = "trial_name",
  estimates = "risk_ratio",
  ci_lower = "rr_lower",
  ci_upper = "rr_upper",
  sample_sizes = "participants",
  events = "events_treatment",
  effect_type = "rr",
  plot_title = "Cardiovascular Risk Reduction",
  x_axis_label = "Risk Ratio (95% CI)",
  reference_line = 1.0
)

Hazard Ratios

Hazard ratios are used in survival analysis:

# Load survival data
data(jforester_survival_hr_data, package = "ClinicoPath")

# Create hazard ratio forest plot
hr_plot <- jforester(
  data = jforester_survival_hr_data,
  study_labels = "study_id",
  estimates = "hazard_ratio",
  ci_lower = "hr_lower",
  ci_upper = "hr_upper",
  sample_sizes = "total_patients",
  events = "deaths",
  effect_type = "hr",
  plot_title = "Survival Analysis: Treatment Effect",
  x_axis_label = "Hazard Ratio (95% CI)",
  reference_line = 1.0
)

Mean Differences

Mean differences are used for continuous outcomes:

# Load mean difference data
data(jforester_mean_diff_data, package = "ClinicoPath")

# Create mean difference forest plot
md_plot <- jforester(
  data = jforester_mean_diff_data,
  study_labels = "study_ref",
  estimates = "mean_difference",
  ci_lower = "md_lower",
  ci_upper = "md_upper",
  sample_sizes = "sample_n",
  events = NULL,
  effect_type = "md",
  plot_title = "Cognitive Score Improvement",
  x_axis_label = "Mean Difference in Cognitive Score",
  reference_line = 0.0,
  log_scale = FALSE
)

Standardized Mean Differences

Standardized mean differences (Cohen’s d) are used for effect size comparisons:

# Load standardized mean difference data
data(jforester_smd_data, package = "ClinicoPath")

# Create standardized mean difference forest plot
smd_plot <- jforester(
  data = jforester_smd_data,
  study_labels = "paper_citation",
  estimates = "cohens_d",
  ci_lower = "smd_lower",
  ci_upper = "smd_upper",
  sample_sizes = "treatment_n",
  events = NULL,
  effect_type = "smd",
  plot_title = "Effect Size Analysis",
  x_axis_label = "Standardized Mean Difference (Cohen's d)",
  reference_line = 0.0,
  log_scale = FALSE
)

Advanced Customization

Color Schemes

The function provides several built-in color schemes:

# Medical color scheme (red)
medical_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  color_scheme = "medical",
  plot_title = "Medical Color Scheme"
)

# Forest green color scheme
forest_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  color_scheme = "forest",
  plot_title = "Forest Green Color Scheme"
)

# Custom colors
custom_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  color_scheme = "custom",
  custom_point_color = "#FF5722",
  custom_ci_color = "#9E9E9E",
  plot_title = "Custom Color Scheme"
)

Point Sizes and Sample Size Weighting

Point sizes can reflect sample sizes to provide visual weight indication:

# Forest plot with sample size weighting
weighted_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  point_size_range = "large",
  plot_title = "Sample Size Weighted Forest Plot"
)

Confidence Levels

Different confidence levels can be specified:

# 99% confidence intervals
conf_99_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  confidence_level = "99",
  plot_title = "99% Confidence Intervals"
)

# 90% confidence intervals
conf_90_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  confidence_level = "90",
  plot_title = "90% Confidence Intervals"
)

Summary Statistics and Meta-Analysis

Summary Effect Display

You can display overall summary statistics:

# Forest plot with summary effect
summary_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  show_summary = TRUE,
  summary_estimate = 1.45,
  summary_ci_lower = 1.23,
  summary_ci_upper = 1.67,
  plot_title = "Meta-Analysis with Summary Effect"
)

Heterogeneity Statistics

Display heterogeneity information:

# Forest plot with heterogeneity statistics
heterogeneity_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  show_heterogeneity = TRUE,
  plot_title = "Forest Plot with Heterogeneity Assessment"
)

Study Weights

Include study weights in the analysis:

# Forest plot with study weights
weights_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  include_weights = TRUE,
  show_table = TRUE,
  plot_title = "Forest Plot with Study Weights"
)

Data Tables and Additional Information

Comprehensive Data Display

Show detailed data tables alongside the forest plot:

# Forest plot with comprehensive data table
comprehensive_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  show_table = TRUE,
  include_weights = TRUE,
  plot_title = "Comprehensive Forest Plot Display"
)

Arrow Labels for Interpretation

Add directional arrows to aid interpretation:

# Forest plot with arrow labels
arrow_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  arrow_labels = TRUE,
  left_arrow_label = "Favors Control",
  right_arrow_label = "Favors Treatment",
  plot_title = "Forest Plot with Directional Labels"
)

Scale and Reference Lines

Logarithmic vs Linear Scales

Choose appropriate scales for your data:

# Logarithmic scale (default for ratios)
log_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  log_scale = TRUE,
  plot_title = "Logarithmic Scale Forest Plot"
)

# Linear scale (for mean differences)
linear_plot <- jforester(
  data = jforester_mean_diff_data,
  study_labels = "study_ref",
  estimates = "mean_difference",
  ci_lower = "md_lower",
  ci_upper = "md_upper",
  sample_sizes = "sample_n",
  events = NULL,
  effect_type = "md",
  log_scale = FALSE,
  plot_title = "Linear Scale Forest Plot"
)

Custom Reference Lines

Set custom reference lines for specific contexts:

# Custom reference line
custom_ref_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  reference_line = 1.5,
  plot_title = "Custom Reference Line (OR = 1.5)"
)

Complex Meta-Analysis Example

Using our complex meta-analysis dataset with multiple variables:

# Load complex meta-analysis data
data(jforester_complex_meta_data, package = "ClinicoPath")

# Display dataset structure
str(jforester_complex_meta_data)
# Comprehensive forest plot with all features
complex_plot <- jforester(
  data = jforester_complex_meta_data,
  study_labels = "study_label",
  estimates = "effect_estimate",
  ci_lower = "lower_ci",
  ci_upper = "upper_ci",
  sample_sizes = "total_participants",
  events = NULL,
  effect_type = "or",
  show_summary = TRUE,
  summary_estimate = 1.25,
  summary_ci_lower = 1.12,
  summary_ci_upper = 1.39,
  show_heterogeneity = TRUE,
  include_weights = TRUE,
  show_table = TRUE,
  color_scheme = "medical",
  plot_title = "Comprehensive Meta-Analysis Forest Plot",
  x_axis_label = "Effect Size (Odds Ratio)",
  arrow_labels = TRUE,
  left_arrow_label = "Favors Control",
  right_arrow_label = "Favors Treatment"
)

Publication and Export Options

Plot Dimensions and Quality

Customize plot dimensions for publication:

# High-quality plot for publication
publication_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  plot_width = 12,
  plot_height = 10,
    dpi = 300,
  echo = TRUE,
  eval = FALSE,
  font_family = "Times",
  export_format = "pdf",
  plot_title = "Publication-Ready Forest Plot"
)

Font Customization

Different font families for various publication requirements:

# Arial font (default)
arial_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  font_family = "Arial",
  plot_title = "Arial Font Forest Plot"
)

# Times New Roman font
times_plot <- jforester(
  data = jforester_meta_analysis_data,
  study_labels = "study_name",
  estimates = "odds_ratio",
  ci_lower = "or_lower_ci",
  ci_upper = "or_upper_ci",
  sample_sizes = "sample_size",
  events = "events",
  effect_type = "or",
  font_family = "Times",
  plot_title = "Times New Roman Font Forest Plot"
)

Interpretation Guidelines

Understanding Effect Measures

Odds Ratios (OR)

  • OR = 1: No difference between groups
  • OR > 1: Increased odds in treatment group
  • OR < 1: Decreased odds in treatment group
  • Clinical significance: Consider both statistical significance and clinical relevance

Risk Ratios (RR)

  • RR = 1: No difference in risk
  • RR > 1: Increased risk in treatment group
  • RR < 1: Decreased risk in treatment group
  • Interpretation: More intuitive than odds ratios for absolute risk

Hazard Ratios (HR)

  • HR = 1: No difference in hazard
  • HR > 1: Increased hazard (worse survival)
  • HR < 1: Decreased hazard (better survival)
  • Time-to-event: Represents instantaneous risk over time

Mean Differences (MD)

  • MD = 0: No difference between groups
  • MD > 0: Higher values in treatment group
  • MD < 0: Lower values in treatment group
  • Units: Same units as original measurement

Standardized Mean Differences (SMD)

  • Small effect: |SMD| = 0.2
  • Medium effect: |SMD| = 0.5
  • Large effect: |SMD| = 0.8
  • Unitless: Allows comparison across different scales

Assessing Heterogeneity

Visual Assessment

  • Overlapping CIs: Suggests consistency
  • Non-overlapping CIs: Suggests heterogeneity
  • Outliers: Studies with unusual results

Statistical Measures

  • I² statistic: Percentage of variation due to heterogeneity
    • 0-25%: Low heterogeneity
    • 25-50%: Moderate heterogeneity
    • 50-75%: Substantial heterogeneity
    • 75-100%: Considerable heterogeneity

Clinical Considerations

Statistical vs Clinical Significance

  • Statistical significance: p < 0.05 (CI doesn’t cross null)
  • Clinical significance: Meaningful difference in practice
  • Minimum clinically important difference: Pre-specified threshold

Confidence Intervals

  • Wide CIs: Greater uncertainty, smaller studies
  • Narrow CIs: Less uncertainty, larger studies
  • Crossing null: Non-significant result

Best Practices

Data Quality

  1. Complete case analysis: Remove studies with missing data
  2. Data validation: Check for logical inconsistencies
  3. Outlier detection: Identify and investigate extreme values

Visualization

  1. Appropriate scale: Log scale for ratios, linear for differences
  2. Clear labeling: Descriptive titles and axis labels
  3. Consistent formatting: Use standard conventions

Reporting

  1. Study characteristics: Include sample sizes, study quality
  2. Statistical methods: Describe analysis approach
  3. Heterogeneity assessment: Report I² and Q-test results
  4. Sensitivity analysis: Test robustness of findings

Troubleshooting Common Issues

Data Format Issues

# Ensure numeric variables are properly formatted
data$odds_ratio <- as.numeric(data$odds_ratio)
data$ci_lower <- as.numeric(data$ci_lower)
data$ci_upper <- as.numeric(data$ci_upper)

Missing Data Handling

# Check for missing values
summary(data[c("odds_ratio", "ci_lower", "ci_upper")])

# Remove incomplete cases
complete_data <- data[complete.cases(data[c("odds_ratio", "ci_lower", "ci_upper")]), ]

Scale Issues

# For ratios, use log scale
log_scale = TRUE

# For differences, use linear scale
log_scale = FALSE

Conclusion

The jforester function provides a comprehensive solution for creating publication-ready forest plots in R. Key features include:

  • Multiple effect types: Support for OR, RR, HR, MD, and SMD
  • Flexible customization: Colors, fonts, sizes, and layouts
  • Statistical integration: Summary statistics and heterogeneity assessment
  • Publication ready: High-quality output for journals and presentations

Forest plots are essential tools for visualizing meta-analysis results and communicating statistical findings effectively. The jforester function makes it easy to create professional-quality forest plots that meet publication standards and enhance the presentation of your research findings.

For more advanced meta-analysis techniques and statistical methods, consider consulting specialized meta-analysis packages and statistical guidance from your institution’s biostatistician or epidemiologist.

References

  1. Cochrane Handbook for Systematic Reviews of Interventions
  2. PRISMA Statement for Reporting Systematic Reviews
  3. Higgins JP, Thompson SG. Quantifying heterogeneity in a meta-analysis. Stat Med. 2002;21(11):1539-58.
  4. Borenstein M, Hedges LV, Higgins JP, Rothstein HR. Introduction to Meta-Analysis. Wiley, 2009.
  5. Riley RD, Higgins JP, Deeks JJ. Interpretation of random effects meta-analyses. BMJ. 2011;342:d549.