The EMMREML package provides an improved mixed model solver that handles a variety of covariance structures for genetic data analysis. It is particularly useful in plant and animal breeding, quantitative genetics, and genome-wide association studies (GWAS).
This vignette introduces the main functionality of the package and shows how to use it through practical examples.
The package provides several key functions:
emmreml: Solves mixed models with known covariance
structure using the ‘EMMA’ algorithmemmremlMultiKernel: Fits models with multiple random
components with known covariance structuresemmremlMultivariate: Solves multivariate Gaussian mixed
models with known covariance structuresgwas: Performs genome-wide association studies with
mixed modelsAdditionally, the package includes functionality for:
You can install the released version of EMMREML from CRAN:
Or the development version from GitHub:
The core functionality of EMMREML is fitting mixed models with known covariance structures. Let’s start with a simple example:
First, let’s generate some example data for our demonstration:
# Generate example data
set.seed(123)
n <- 100 # number of samples
# Create fixed effects
X <- cbind(1, rnorm(n))
colnames(X) <- c("intercept", "x")
# Create a realistic kinship matrix
Z <- diag(n)
K_raw <- matrix(rnorm(n*20), n, 20)
K <- tcrossprod(K_raw)
diag(K) <- diag(K) + 1e-6 # ensure positive definiteness
K <- K / mean(diag(K)) # Scale K
# Simulate data from the model
u <- crossprod(chol(K), rnorm(n)) * sqrt(2) # random effect with Var=2*K
e <- rnorm(n) # residual with Var=1
y <- 10 + 2 * X[, 2] + u + e
# Create data frame
df <- data.frame(y = y, x = X[, 2], id = 1:n)We can fit a mixed model using the emmreml function:
# Fit model
result <- emmreml(y = df$y,
X = cbind(1, df$x), # Intercept + x
Z = diag(nrow(df)), # Identity for observations
K = K)
# Display results
cat("Variance components:\n")
#> Variance components:
cat("Genetic variance (Vu):", result$Vu, "\n")
#> Genetic variance (Vu): 0.7811974
cat("Residual variance (Ve):", result$Ve, "\n")
#> Residual variance (Ve): 0.8963003
cat("\nFixed effects:\n")
#>
#> Fixed effects:
names(result$betahat) <- c("Intercept", "x")
print(result$betahat)
#> [,1]
#> [1,] 9.848929
#> [2,] 2.128694
#> attr(,"names")
#> [1] "Intercept" "x"The emmremlMultiKernel function allows you to fit models
with multiple random components. This is useful when you have multiple
sources of genetic effects or environmental factors that you want to
model separately.
# Create a second kinship matrix
set.seed(456)
K2_raw <- matrix(rnorm(n*15), n, 15)
K2 <- tcrossprod(K2_raw)
diag(K2) <- diag(K2) + 1e-6
K2 <- K2 / mean(diag(K2))
# Simulate new data with two random components
u1 <- crossprod(chol(K), rnorm(n)) * sqrt(1.5) # first random effect
u2 <- crossprod(chol(K2), rnorm(n)) * sqrt(0.8) # second random effect
e <- rnorm(n) * sqrt(0.7) # residual
y_mk <- 10 + 2 * X[, 2] + u1 + u2 + e
# Create data frame
df_mk <- data.frame(y = y_mk, x = X[, 2], id = 1:n)
# List of kernel matrices
K_list <- list(K1 = K, K2 = K2)
# Fit multi-kernel model
mk_result <- emmremlMultiKernel(y = df_mk$y,
X = cbind(1, df_mk$x),
Z = diag(nrow(df_mk)),
K = K_list)
# Display results
cat("Variance components:\n")
print(mk_result$varcomp)
cat("\nFixed effects:\n")
names(mk_result$betahat) <- c("Intercept", "x")
print(mk_result$betahat)EMMREML can also handle multivariate mixed models, where you analyze
multiple response variables simultaneously using the
emmremlMultivariate function:
# Generate multivariate example data
p <- 3 # number of traits
# Create covariance matrices
Vg <- matrix(c(2, 1, 0.5, 1, 1.5, 0.75, 0.5, 0.75, 1), p, p)
Ve <- matrix(c(1, 0.2, 0.1, 0.2, 0.8, 0.15, 0.1, 0.15, 0.5), p, p)
# Simulate data
B <- matrix(c(10, 2, 5, 1, 3, 0.5), 2, p) # fixed effects for 3 traits
G <- matrix(rnorm(n*p), n, p) %*% chol(Vg) # random effects
E <- matrix(rnorm(n*p), n, p) %*% chol(Ve) # errors
Y <- X %*% B + G + E
# Create data frame
df_mv <- data.frame(y1 = Y[,1], y2 = Y[,2], y3 = Y[,3], x = X[,2], id = 1:n)
# Fit multivariate model
mv_result <- emmremlMultivariate(formula = cbind(y1, y2, y3) ~ x,
random = ~ id,
data = df_mv,
K = K)
# Display results
cat("Genetic covariance matrix (Vg):\n")
print(mv_result$Vg)
cat("\nError covariance matrix (Ve):\n")
print(mv_result$Ve)
cat("\nFixed effects:\n")
print(mv_result$beta)The package includes functionality for performing GWAS with mixed models, which helps control for population structure:
# Generate GWAS example data
p <- 1000 # number of markers
markers <- matrix(sample(c(0, 1, 2), n*p, replace=TRUE), nrow=n, ncol=p)
colnames(markers) <- paste0("SNP", 1:p)
# Select some causal variants
causal_idx <- c(100, 300, 700)
betas <- rep(0, p)
betas[causal_idx] <- c(0.5, 0.4, 0.3)
# Create genetic values from markers
g <- markers %*% betas
# Create phenotype for GWAS
y_gwas <- 10 + g + u + e
df_gwas <- data.frame(y = y_gwas, x = X[, 2], id = 1:n)
# Run GWAS
gwas_result <- gwas(
formula = y ~ x,
random = ~ id,
data = df_gwas,
markers = markers,
K = K,
accelerated = TRUE
)
# Display top results
head(gwas_result$results[order(gwas_result$results$p_value),], 10)The kinship module provides functions for processing
marker data and calculating different types of kinship matrices:
The EMMREML package provides a comprehensive set of tools for fitting mixed models with known covariance structures. It is particularly useful for genetic data analysis, including GWAS and multivariate trait analysis. The package offers optimized implementations for improved performance, especially when dealing with identity kinship matrices.
For more detailed information, refer to the function documentation
using the ? operator, e.g., ?emmreml.