--- title: "Univariable Functional Mendelian Randomization" author: "Nicole Fontana" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Univariable Functional Mendelian Randomization} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 5 ) ``` ## Overview This vignette demonstrates **Univariable Functional Mendelian Randomization (U-FMR)** for estimating the time-varying causal effect of a **single longitudinal exposure** on a health outcome. ### When to Use U-FMR Use univariable estimation (`mvfmr_separate()` with `G2 = NULL`) when: - You have a **single exposure** of interest - No need to adjust for other exposures ## Installation ```{r install, eval=FALSE} devtools::install_github("NicoleFontana/mvfmr") ``` ```{r load} library(mvfmr) library(fdapace) library(ggplot2) ``` ## Example: Single Exposure Analysis ### Step 1: Simulate Data ```{r simulate} set.seed(12345) # Generate exposure data (we'll only use X1) sim_data <- getX_multi_exposure( N = 300, J = 25, nSparse = 10 ) cat("Data simulated:\n") cat(" Sample size:", nrow(sim_data$details$G), "\n") cat(" Instruments:", ncol(sim_data$details$G), "\n") ``` ### Step 2: Generate Outcome We create an outcome where **only X1 has a causal effect**: ```{r outcome} outcome_data <- getY_multi_exposure( sim_data, X1Ymodel = "2", # Linear effect: β(t) = 0.02×t X2Ymodel = "0", # No effect from X2 X1_effect = TRUE, X2_effect = FALSE, # X2 does not affect Y outcome_type = "continuous" ) cat("Outcome summary:\n") summary(outcome_data$Y) ``` ### Step 3: FPCA for Single Exposure ```{r fpca} # FPCA for exposure 1 only fpca1 <- FPCA( sim_data$X1$Ly_sim, sim_data$X1$Lt_sim, list(dataType = 'Sparse', error = TRUE, verbose = FALSE) ) cat("FPCA completed:\n") cat(" Components selected:", fpca1$selectK, "\n") cat(" Variance explained:", round(sum(fpca1$lambda[1:fpca1$selectK]) / sum(fpca1$lambda) * 100, 1), "%\n") ``` ### Step 4: Univariable Estimation Estimate the causal effect using `mvfmr_separate()` with **only one exposure**: ```{r estimation} result <- mvfmr_separate( G1 = sim_data$details$G, # Instruments for X1 G2 = NULL, # No second exposure fpca_results = list(fpca1), Y = outcome_data$Y, outcome_type = "continuous", method = "gmm", max_nPC1 = 4, max_nPC2 = 4, # Not used when G2 = NULL n_cores = 1, true_effects = list(model1 = "2", model2 = "0"), verbose = FALSE ) print(result) ``` ### Step 5: Visualize Time-Varying Effect ```{r plot_effect, fig.width=7, fig.height=5} plot(result) ``` The solid colored lines show the estimated time-varying causal effects, with shaded bands representing 95% confidence intervals. The dashed red lines (when present) indicate the true time-varying effects used in the simulation. ### Step 6: Extract Results ```{r extract} # Coefficients for basis functions cat("Estimated coefficients:\n") print(round(coef(result, exposure = 1), 4)) # Time-varying effect curve cat("\nFirst 10 time points of β(t):\n") head(result$exposure1$effect, 10) ``` ### Step 7: Performance Metrics ```{r performance} cat("Performance:\n") cat(" MISE:", round(result$exposure1$performance$MISE, 6), "\n") cat(" Coverage:", round(result$exposure1$performance$Coverage, 3), "\n") cat(" Components used:", result$exposure1$nPC_used, "\n") ``` ## Binary Outcomes U-FMR also works with binary outcomes: ```{r binary, eval=FALSE} # Generate binary outcome outcome_binary <- getY_multi_exposure( sim_data, X1Ymodel = "2", X2Ymodel = "0", X1_effect = TRUE, X2_effect = FALSE, outcome_type = "binary" ) # Estimate with control function result_binary <- mvfmr_separate( G1 = sim_data$details$G, G2 = NULL, fpca_results = list(fpca1), Y = outcome_binary$Y, outcome_type = "binary", method = "cf", # Control function for binary max_nPC1 = 3, n_cores = 1, verbose = FALSE ) print(result_binary) cat("Cases:", sum(outcome_binary$Y == 1), "\n") cat("Controls:", sum(outcome_binary$Y == 0), "\n") ``` ## Advanced Topics ### Available Effect Models The package includes 10 pre-defined time-varying effect shapes: - `"0"`: No effect (null) - `"1"`: Constant (β = 0.1) - `"2"`: Linear increasing - `"3"`: Linear decreasing - `"4"`: Early life effect - `"5"`: Late life effect - `"6"`: Early decreasing - `"7"`: Late increasing - `"8"`: Quadratic (U-shape) - `"9"`: Cubic ### Bootstrap Inference ```{r bootstrap, eval=FALSE} # Get robust confidence intervals via bootstrap result_boot <- mvfmr_separate( G1 = sim_data$details$G, G2 = NULL, fpca_results = list(fpca1), Y = outcome_data$Y, outcome_type = "continuous", bootstrap = TRUE, n_bootstrap = 100, max_nPC1 = 4, verbose = FALSE ) # Bootstrap CIs are stored in result_boot$exposure1$... ``` ### Two-Sample Design If you have GWAS summary statistics instead of individual-level outcome data: ```{r twosample, eval=FALSE} # Simulate GWAS summary statistics by_outcome <- rnorm(25, 0.02, 0.01) sy_outcome <- runif(25, 0.005, 0.015) result_2sample <- fmvmr_separate_twosample( G1_exposure = sim_data$details$G, G2_exposure = NULL, fpca_results = list(fpca1), by_outcome1 = by_outcome, by_outcome2 = NULL, sy_outcome1 = sy_outcome, sy_outcome2 = NULL, ny_outcome = 50000, max_nPC1 = 3, verbose = FALSE ) print(result_2sample) ``` ## Next Steps ### Learn More - **Multivariable FMR**: See `vignette("multivariable-fmr")` for joint estimation - **Complete examples**: Check `inst/examples/test_U-FMR.R` for all scenarios - **Manuscript**: See paper for methodological details ## Citation If you use this package, please cite: > Fontana, N., Ieva, F., Zuccolo, L., Di Angelantonio, E., & Secchi, P. (2025). Unraveling time-varying causal effects of multiple exposures: integrating Functional Data Analysis with Multivariable Mendelian Randomization. *arXiv preprint arXiv:2512.19064*. ## Session Info ```{r session} sessionInfo() ```