intraHostVariants: SNVs from Multiple Anatomical Sites

Introduction

Intra-host viral diversity (or quasispecies) drives resilience to the immune responses and therapeutical interventions, while also fostering the emergence of new lineages (Andino and Domingo 2015; Eigen 1996; Jones 2025). The intraHostVariants dataset contains SARS-CoV-2 single nucleotide variants (SNVs) identified from autopsies of individuals with postmortem viral detection and no documented immunocompromise (Manrique et al. 2024).

Although MetaEntropy is tailored primarily for high-density wastewater data, it is also effective for quantifying and analyzing intra-host viral protein diversity, as demonstrated in this vignette. For specialized or comprehensive quasispecies characterization, dedicated tools such as QSutils (Guerrero-Murillo and Gregori i Font 2018) are recommended.

First load the required packages:

lapply(c("MetaEntropy", "ggplot2", "patchwork", "tidyr"),
       library, character.only = TRUE
)

Data Structure and Characteristics

intraHostVariants is a data.frame containing information on 213 SNVs inferred across lung, intestinal, cardiac, renal, and hepatic tissues. Its 16 columns include everything required by MetaEntropy, alongside experimental metadata and standard outputs typical of variant caller tables. The underlying bioinformatic workflow is detailed in the intraHostVariants documentation.

SARS-CoV-2 infections primarily cause respiratory illness, but the virus can spread systemically and replicate independently across different anatomical sites (Stein et al. 2022; Manrique et al. 2024). Consequently, individual tissues may harbor exclusive SNVs or share them at varying frequencies. This within-host diversity is well illustrated by intraHostVariants.

First, let’s look at the distribution of SNVs across anatomical compartments:

addmargins(
       table(intraHostVariants$case,
         intraHostVariants$organ
         ),
       margin = 2
)
#>      
#>       heart intestine kidney liver lung Sum
#>   c18    12        10      4     0    4  30
#>   c24    40        21     18     4    2  85
#>   c28     5        30     36    12    5  88
#>   c5      2         0      1     4    3  10

Two to five SNVs are recorded per respiratory sample, closely aligning with ranges reported in prior swab-based studies (Jones 2025). However, the total number of SNVs recorded per individual ranges from 10 to 88 across all tissues.

Next, let’s examine the distribution of SNV frequencies. First, we pivot the dataset to place the alternative amino acid frequencies into separate columns for each anatomical compartment:

wide_ihv <- tidyr::pivot_wider(intraHostVariants,
         names_from = organ,
         values_from = alt_aa_freq,
         # Use 0 (instead of NA) for undetected
         # mutations.
         values_fill = list(alt_aa_freq = 0)
)

We can now use wide_ihv to visualize these variant frequencies across tissues with parallel coordinates plots:

par(mfcol = c(4,1), mar = c(2, 4, 2, 2) + 0.1)
for(case in sort(unique(wide_ihv$case))){
    thisCase <- t(wide_ihv[wide_ihv$case == case, c(15, 16, 17, 18, 19)])
    matplot(thisCase, type = "b", pch = 19, col = rgb(0, 0, 0, 0.4), lty = 1,
        xaxt = "n", xlab = "",
        main = sub("c", "case ", case),
        ylab = "SNV frequency"
    )
    axis(side = 1, at = 1:5, labels = rownames(thisCase)
    )
}

This reveals that the viral quasispecies varies considerably between anatomical sites. For instance, the lung and heart in case 18 harbor three high-frequency SNVs that are absent from other organs:

intraHostVariants[intraHostVariants$case == "c18" & intraHostVariants$alt_aa_freq > 0.2 ,
                  c(1, 2, 10, 13, 14, 15, 16)]
#>    case organ protein aa_position ref_aa alt_aa alt_aa_freq
#> 12  c18 heart   nsp10         121      G      V    0.350514
#> 18  c18 heart   nsp15         145      E      E    0.985571
#> 38  c18  lung    nsp3         534      A      A    0.988260

Package Integration

Intra-host SNVs can be synonymous or non-synonymous, and the impact of non-synonymous mutations varies depending on whether the resulting amino acid substitution is conservative or radical. From a virological perspective, these phenotypic changes are particularly relevant because they are more likely to alter viral physiology. MetaEntropy is particularly useful here because it calculates amino acid entropy and allows residues to be classified based on their physicochemical properties, offering a nuanced view of functional protein diversity. We will now use MetaEntropy to evaluate amino acid diversity across anatomical sites within each individual.

First, we split the dataset into separate data.frame objects according to the experimental design strata (organ and case), storing them as a list:

strata <- split(intraHostVariants,
                    list(intraHostVariants$organ, intraHostVariants$case),
                    sep = "_", drop = TRUE
)

Create a custom genome

The SNVs of intraHostVariants were inferred using the genomic sequence of the reference strain Wuhan-Hu-1, which is the same as that of the reference genome provided with MetaEntropy (list object mn908947.3). However, mn908947.3 splits the nsp12 mature peptide into its ORF1a- and ORF1b-derived segments (nucleotides 13,442–13,468 and 13,468–16,236, respectively) to accommodate the -1 ribosomal frameshift. In contrast, intraHostVariants does not use this split encoding; instead, nsp12 is represented as a single continuous block spanning nucleotides 13,442–16,236. Therefore, the object passed to the genome argument of getEntropySignature() must reflect this single continuous region. We can modify mn908947.3 accordingly:

mn908947.3.ihv <- mn908947.3
# Get the nsp12 3' end and assign it to nsp12_end
nsp12_rows <- mn908947.3.ihv$CDS$protein %in% c("nsp12a", "nsp12b")
nsp12_end <- max(mn908947.3.ihv$CDS$end[nsp12_rows])
# Create an entry for nsp12 from nsp12a
mn908947.3.ihv$CDS$protein[mn908947.3.ihv$CDS$protein == "nsp12a"] <- "nsp12"
# Update the 3' end
mn908947.3.ihv$CDS$end[mn908947.3.ihv$CDS$protein == "nsp12"] <- nsp12_end
# dismiss the old nsp12b annotation
mn908947.3.ihv$CDS <- mn908947.3.ihv$CDS[mn908947.3.ihv$CDS$protein != "nsp12b", ]
# tidy up the environment
rm(nsp12_rows, nsp12_end)

Entropy computation

Now we apply getEntropySignature() to each partition:

profiles <- lapply(strata, function(df) {
               getEntropySignature(df, position = "POS", ref = "REF", alt = "ALT",
                           genome = mn908947.3.ihv
               )
})

Profiles comparison

Now we can visually compare entropy across anatomical sites using heatmap_entropyProfiles():

heatmap_entropyProfiles(!!!profiles)

The heatmap indicates that total intra-host viral entropy extends beyond what is observed in the respiratory tract alone. We can summarize this difference across mature viral proteins by grouping organs into respiratory versus non-respiratory compartments:

combined_entropy <- lapply(profiles, function(p) p$Entropy) |> do.call(rbind, args = _)
combined_entropy <- cbind(combined_entropy,
                          system = factor(ifelse(grepl("lung", rownames(combined_entropy)),
                                                       "respiratory system", "other"),
                                          levels = c("respiratory system", "other")
                                   )
                    )
# Plot in genomic order
combined_entropy$protein <- factor(
                                   combined_entropy$protein,
                                   levels = mn908947.3.ihv$CDS$protein
)
bp <- ggplot2::ggplot(data = combined_entropy, aes(x = protein, y = entropy)) +
    ggplot2::geom_boxplot(varwidth = T) +
    ggplot2::facet_wrap(~ system, ncol = 1, scales = "free_y") +
    ggplot2::scale_x_discrete(drop = FALSE) +
    ggplot2::theme_bw() +
    ggplot2::theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))
bp

Overall, this vignette demonstrates how MetaEntropy can untangle proteomic variation across viral populations and subpopulations. These insights offer directions for future research. For instance, in the case of viral quasispecies shown here, the entropy profiles highlight avenues to explore, such as how localized proteomic variation influences immune responses, or the extent to which swab sampling captures total intra-host viral diversity.

References

Andino, Raul, and Esteban Domingo. 2015. “Viral Quasispecies.” Virology 479-480 (May): 46–51. https://doi.org/10.1016/j.virol.2015.03.022.

Eigen, M. 1996. “On the Nature of Virus Quasispecies.” Trends in Microbiology 4 (6): 216–18. https://doi.org/10.1016/0966-842x(96)20011-3.

Guerrero-Murillo, Mercedes, and Josep Gregori i Font. 2018. “QSutils.” Bioconductor. https://doi.org/10.18129/B9.BIOC.QSUTILS.

Jones, Leandro R. 2025. “Intra-Host Variability of Sars-Cov-2: Patterns, Causes and Impact on Covid-19.” Virology 603 (February): 110366. https://doi.org/10.1016/j.virol.2024.110366.

Manrique, Julieta M., Santiago Maffia‐Bizzozero, M. Victoria Delpino, Jorge Quarleri, and Leandro R. Jones. 2024. “Multi‐Organ Spread and Intra‐Host Diversity of Sars‐CoV‐2 Support Viral Persistence, Adaptation, and a Mechanism That Increases Evolvability.” Journal of Medical Virology 96 (12). https://doi.org/10.1002/jmv.70107.

Stein, Sydney R., Sabrina C. Ramelli, Alison Grazioli, Joon-Yong Chung, Manmeet Singh, Claude Kwe Yinda, Clayton W. Winkler, et al. 2022. “SARS-Cov-2 Infection and Persistence in the Human Body and Brain at Autopsy.” Nature 612 (7941): 758–63. https://doi.org/10.1038/s41586-022-05542-y.