From 76cbb203161eadc9e69801cc8662e116e74829a8 Mon Sep 17 00:00:00 2001 From: jhudsl-robot Date: Wed, 21 Feb 2024 18:18:42 +0000 Subject: [PATCH] Render bookdown --- docs/authors.html | 2 +- docs/hgv_lab.docx | Bin 8394696 -> 8394579 bytes docs/index.html | 3 --- docs/reading-in-data.html | 2 +- docs/search_index.json | 2 +- 5 files changed, 3 insertions(+), 6 deletions(-) diff --git a/docs/authors.html b/docs/authors.html index 764a5b1c..5b0ec029 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -471,7 +471,7 @@

Authors

## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz Etc/UTC -## date 2023-07-28 +## date 2024-02-21 ## ## ─ Packages ─────────────────────────────────────────────────────────────────── ## package * version date lib source diff --git a/docs/hgv_lab.docx b/docs/hgv_lab.docx index bb596248685762baf2adc557aeda829bbd6ca34f..248e38e909193b9c5da13d218cb06fea86f180ce 100644 GIT binary patch delta 115999 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 delta 116001 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

1.0.0.1 Instructor

1.0.0.2 Schedule & Logistics

-

Class is Tuesdays from 3-3:50PM, in UTL G89.

-

Please bring your laptop with you to every class. If you don’t have a working laptop, contact me so that we can find a solution. -

diff --git a/docs/reading-in-data.html b/docs/reading-in-data.html index a807118c..29aec102 100644 --- a/docs/reading-in-data.html +++ b/docs/reading-in-data.html @@ -414,7 +414,7 @@

10.8 Reading in data

We can provide the location of the downloaded files to the eigenstrat() function, which then constructs an EIGENSTRAT object to be used for downstream analysis.

# read in eigenstrat files
-snps <- eigenstrat(prefix)
+snps <- eigenstrat("./snps/snps")
 snps
## EIGENSTRAT object
 ## =================
diff --git a/docs/search_index.json b/docs/search_index.json
index 9b4b7fbf..91b66455 100644
--- a/docs/search_index.json
+++ b/docs/search_index.json
@@ -1 +1 @@
-[["index.html", "Human Genome Variation Lab 1 Homepage", " Human Genome Variation Lab 1 Homepage This is the course homepage and digital textbook for Human Genome Variation with Computational Lab (AS.020.321). 1.0.0.1 Instructor Rajiv McCoy, rajiv.mccoy[at]jhu.edu 1.0.0.2 Schedule & Logistics Class is Tuesdays from 3-3:50PM, in UTL G89. Please bring your laptop with you to every class. If you don’t have a working laptop, contact me so that we can find a solution. Session Content Session 1: The reference genome & genome browsers Session 2: De novo mutations Session 3: Linkage disequilibrium Session 4: Simulating evolution Session 5: Population structure – part I Session 6: Population structure – part II Session 7: Genome-wide association studies – part I Session 8: Genome-wide association studies – part II Session 9: Scans for selection – part I Session 10: Scans for selection – part II Session 11: Archaic admixture Session 12: Gene expression Session 13: Coronavirus phylogenetics "],["genome-browsers.html", "2 Genome browsers", " 2 Genome browsers In this module, we’ll learn how to use the UC Santa Cruz (UCSC) Genome Browser and the Integrative Genomics Viewer (IGV), two extremely popular tools for visualizing genomic data. 2.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Explain why a reference genome is an important resource for genomics research. Use the UCSC genome browser to find genomic features in a region of interest. Describe the data contained in a file of sequencing reads. Load and interpret sequencing data in IGV. "],["dna-sequencing-data.html", "2.1 DNA sequencing data", " 2.1 DNA sequencing data These days, the vast majority of genomic data is generated through high-throughput Illumina short-read sequencing. The broad steps of this sequencing process are: Extract DNA Fragment DNA Prepare for sequencer (add adapters, etc.) Amplify DNA Sequencing (add fluorescently labeled nucleotides that are read by a digital camera) Fig. 1 (source). Schematic of Illumina short-read sequencing. This sequencing approach is fast and cost efficient, but introduces two main limitations. Because of the fragmentation step, the resulting sequencing reads are extremely short (~150 bp). We don’t know where in the genome the sequencing reads came from. (This is a limitation common to nearly every sequencing experiment.) "],["assembling-a-genome.html", "2.2 Assembling a genome", " 2.2 Assembling a genome When the human genome is 3 billion base pairs long, assembling short sequencing reads into a full genome is a major computational challenge. How is genome assembly performed? We can combine sequencing reads that partially overlap with each other into longer sequences. Fig. 2. Using overlapping sequencing reads to assemble a genome. Which regions of the genome are hardest to assemble? Ideally, with enough sequencing data, we would be able to reconstruct an entire genome from overlapping reads. In practice, genome assembly is complicated by repetitive DNA – sequences in different regions of the genome that are completely or nearly identical. These repeats make it difficult (or impossible) to determine the order of the sequences around them, or how many copies of the repeat there are. Fig. 3. How repetitive sequences affect genome assembly. Resolving repetitive regions requires sequencing reads that are longer than the repeat itself, which allow us to determine the flanking sequences on the sides of the repeat. Using such long-read sequencing technology (i.e., PacBio and Nanopore sequencing), the Telomere-to-Telomere consortium was able to create a complete, ungapped assembly of the human genome in 2021. "],["the-human-reference-genome.html", "2.3 The human reference genome", " 2.3 The human reference genome Having to assemble an entire genome every time you sequence a new individual is a hassle (and often infeasible, if you don’t have enough sequencing data). Instead, we typically align sequencing reads to a reference genome – a high-quality genome assembly for that species, which we use to guide our analysis. The human reference genome was initially assembled in 2000 by the Human Genome Project, and has undergone decades of refinement since. The current version of this reference, which we’ll be using, is hg38. Whose DNA was sequenced for the human reference genome? DNA from multiple individuals was sequenced to construct the reference genome. Its sequence is a mosaic of these individuals’ DNA. You can classify the ancestry of different parts of hg38 by comparing its sequence to DNA from different populations. From this, we know that around 70% of hg38 comes from one individual, called RP11, who likely had African American ancestry. Fig. 4. Sample composition of the human reference genome. "],["ucsc-genome-browser.html", "2.4 UCSC genome browser", " 2.4 UCSC genome browser What does the human reference genome actually look like? We can view it in the UC Santa Cruz (UCSC) genome browser, an interactive website for viewing genomes – both the human reference and reference genomes for several other species. The browser also displays genome annotations, such as the locations of genes and clinically relevant genetic variants. Go to the UCSC genome browser. 2.4.1 Homepage There are a few key areas of this page: Browse/Select Species – choose the species Human Assembly – choose the version of the human reference genome Position/Search Term – type in a specific position (ex: chr2:25160915), region (ex: chr1:100000-200000), or gene name (ex: HLA-A) Fig. 5. UCSC genome browser homepage. In Position/Search Term, type in a gene you’re interested in and hit enter. Why are there different versions of the reference genome? You may have noticed that the name of the reference genome we’re using is GRCh38 or hg38, which stands for Genome Reference Consortium Human Build 38 – version 38 of the reference genome. Over time, the Genome Reference Consortium makes improvements to the reference genome by closing gaps, fixing problems, and resolving repetitive regions. hg38, the most recent version, was released in 2013. "],["viewing-one-region-of-the-genome.html", "2.5 Viewing one region of the genome", " 2.5 Viewing one region of the genome Once you hit enter, you should end up on a page like this: Fig. 6. Viewing one genomic region in the UCSC genome browser. The default display includes these broad groups of annotations: Navigation: Buttons for zooming and moving around (you can also move by clicking the display, holding, and moving your mouse); current region; search bar Position: Current position on the chromosome; current base pair position Genes: Gene annotations; gene expression by tissue; gene regulatory elements (CREs) Species comparison: DNA sequence conservation across vertebrates; regions that align with the genomes of other vertebrates Variation: Genetic variants in the dbSNP database; repeat elements Inspecting a specific track If you’re interested in more information about a specific track – for example, the POMC gene annotation – you can click on that element to go to a webpage with more details. Fig. 7. Clicking on the POMC gene track. (Note that if you click on whitespace instead of an annotation element, it will change the track’s display density instead.) Fig. 8. Clicking on whitespace to expand the RefSeq genes track. Customizing the display tracks The tracks that are automatically displayed are just a small subset of what’s available. You can select which tracks you want to see, and set their display density, by scrolling down on the page. To add a new track to your browser view, click the drop-down menu below that track and select any of the options besides hide. Here we’re viewing the “Clone Ends” track, which shows the different individuals that were sequenced to create this section of the reference genome. Fig. 9. Adding the “clone ends” track to the browser. Click the refresh button in the upper right to reload the genome view. You should see something like this, showing that this region of the reference genome was sequenced in three individuals (CH17, CTD, and RP11): Fig. 10. Viewing the “clone ends” track. "],["igv.html", "2.6 IGV", " 2.6 IGV While the UCSC genome browser lets you view the reference genome itself, we’re often interested in looking at sequencing data – sequencing reads that are aligned to the reference genome. For this we use the Integrative Genomics Viewer (IGV). Go to the IGV web app. 2.6.1 Homepage The IGV homepage is fairly empty because we haven’t loaded any sequencing reads to look at, and also because we’re zoomed too far out to see anything. The Genome tab in the upper right lets you choose which reference genome to work in. The default is hg38 A drop-down menu and search bar below the header allow you to pick a chromosome and genomic position Fig. 11. The IGV homepage. We haven’t chosen a chromosome yet, so all of them are displayed below the drop-down menu. Click on one to go to a zoomed-in view of that particular chromosome. "],["navigating-igv.html", "2.7 Navigating IGV", " 2.7 Navigating IGV Once you’ve clicked on a chromosome, zoom in until you can see colors on the top track. This track displays the DNA sequence, colored by nucleotide. The track below the DNA sequence has gene annotations from RefSeq. Fig. 12. Viewing a gene in IGV. "],["loading-sequencing-data.html", "2.8 Loading sequencing data", " 2.8 Loading sequencing data Click on the Genome drop-down menu and switch to the Human (hg38 1kg/GATK) reference genome. This version of the hg38 reference has sequencing data already loaded into the IGV web app. Once you’ve switched references, click Tracks -> 1KG Low Coverage Alignments. This gives you a list of sample to load sequencing data from. Click any sample and then OK. Fig. 13. Loading reads from a 1000 Genomes sample. "],["the-1000-genomes-project.html", "2.9 The 1000 Genomes Project", " 2.9 The 1000 Genomes Project Where did this sequencing data come from? In 2015, a study called the 1000 Genomes Project (1KG or 1KGP) sequenced 3,202 individuals from 26 globally diverse populations. Because this data is publicly available, it’s become one of the most widely used datasets in human genetics. Notably, 1KGP still excludes key regions of the world – such as Oceania, the Middle East, native American populations in North America, and many populations within Africa. Fig. 14. Regions sampled by the 1000 Genomes Project. Go to the 1000 Genomes Project website and click the Data tab. Then click the link to the data portal. Fig. 15. The data portal includes information about the samples in this dataset. Choose any individual and copy their sample ID (ex: HG00138). We can use this sample ID to find this individual’s raw sequencing data in the Sequence Read Archive (SRA). "],["sra.html", "2.10 SRA", " 2.10 SRA Search for the sample ID you chose in SRA. You should see something like this, where every item is a sequencing dataset generated for this sample. Fig. 16. Finding sequencing data in SRA. 2.10.1 Previewing sequencing data Choose any sequencing dataset, and then click on any item in the Run table at the bottom. This takes you to a page that displays a specific sequencing run (i.e., one use of a sequencing machine). Go to the Reads tab. Fig. 17. The Reads tab in SRA. The right-hand panel shows one sequencing read from this run. Note that the sequence of this read is around 100bp long – the average length for short-read Illumina sequencing. All sequencing data looks like this! It’s just a text file filled with the IDs and DNA/RNA sequences of your reads. "],["viewing-sequencing-reads-in-igv.html", "2.11 Viewing sequencing reads in IGV", " 2.11 Viewing sequencing reads in IGV Now that we’ve seen what raw sequencing data looks like, let’s look at it in IGV. Return to your IGV tab, where you should have one sample’s DNA sequencing data loaded. Make sure you’re zoomed in enough for the data to display. Fig. 18. The Reads tab in SRA. The top track is a histogram of sequencing coverage (i.e., how many reads there are at that position in the genome). The bottom track shows the reads themselves. How do we know where in the genome each read belongs? We match the sequence of the read to the sequence of the reference genome (called alignment). With 100bp reads, the probability that a match occurs by chance is \\(\\frac{1}{4^{100}}\\), or \\(6.2 * 10^{-61}\\). Extracting alignment information in IGV If you click on a specific read, IGV will display additional information about it, including: The exact position it aligns to The mapping quality (a score indicating how uniquely it aligns to this position) If you’re working with paired-end sequencing data, where its paired read is Fig. 19. Viewing additional info for one sequencing read. "],["interpreting-igv-alignments.html", "2.12 Interpreting IGV alignments", " 2.12 Interpreting IGV alignments Sequencing reads in IGV are colored at bases where they differ from the reference genome. These differences can be caused by either real genetic variation or sequencing error. How would you distinguish these two? Fig. 20. Two of these colored bases are probably real SNPs, and two are probably errors. The sequencing coverage track also colors the positions that it thinks are real variants. In the screenshot above, which spans about 2kb, there are two SNPsin the coverage track. This pattern holds more broadly through the genome – humans carry about one SNP every 1,000 bases. Is one SNP every 1,000bp a lot or a little? Humans actually have much lower amounts of genetic variation than many species, including many of the great apes. This is mostly the result of human evolutionary history. Because the effective size of human populations has historically been low, with only very recent expansion, the gene pool is still fairly homogenous, with many rare variants and few common ones. "],["conclusion.html", "2.13 Conclusion", " 2.13 Conclusion In this lab, we explored several of the most commonly used websites in genomics: 2.13.0.1 Genome browsers UCSC genome browser: Used to explore features of the human genome If you discover an interesting SNP in your research, you might look it up in the UCSC browser to see which genes it’s in/near, if it overlaps with any repetitive elements, etc. IGV: Used to visualize sequencing data It’s common practice to look at your sequencing reads in IGV to check alignment quality, verify that SNPs look like real variants and not errors, etc. 2.13.0.2 Data repositories 1000 Genomes Project: One of the largest and most diverse datasets of human sequencing data Data from 1000 Genomes is frequently used in human genetics studies SRA: A repository for publicly available sequencing data Genetics studies deposit their data in SRA if it can be made publicly available (i.e., if it has no identifiable information) "],["homework.html", "2.14 Homework", " 2.14 Homework 2.14.0.1 Assignment Create an account on Posit Cloud. "],["discovering-mutations.html", "3 Discovering mutations", " 3 Discovering mutations In this module, we’ll use DNA sequencing data from human families to explore the relationship between parental age and de novo mutations in their children. 3.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Create plots to visualize the relationship between two variables. Interpret the results of a linear model. Compare the impact of maternal vs. paternal age on de novo mutation counts. Explain what a confidence interval is and why it’s useful. "],["de-novo-mutations.html", "3.1 De novo mutations", " 3.1 De novo mutations Mutation and recombination are two biological processes that generate genetic variation. When these phenomena occur during gametogenesis, the changes that they make to DNA are passed down to the next generation through germline cells (i.e., sperm and oocyte). De novo mutations (DNMs) arise from errors in DNA replication or repair. These mutations can be single-nucleotide polymorphisms (SNPs) or insertions and deletions of DNA. Every individual typically carries around 70 de novo SNPs that were not present in either of their parents. Fig. 1. Sources of DNMs in gametogenesis. "],["recombination.html", "3.2 Recombination", " 3.2 Recombination Crossovers, or meiotic recombination, occur during prophase of meiosis I, when homologous chromosomes pair with each other. Double-strand breaks are deliberately generated in the DNA, and are then cut back and repaired based on the sequence of the homologous chromosome. These repairs can sometimes resolve in a crossover event, where sections of DNA are swapped between chromosomes. Because the sequences of homologous chromosomes differ at sites where they carry different alleles, recombination generates genetic diversity by creating new haplotypes, or combinations of alleles. Crossovers are required for meiosis in most organisms because they ensure proper homologous chromosome pairing and segregation. Humans experience 1-4 crossover events per chromosome, with longer chromosomes having more crossovers. Fig. 2. Possible outcomes for double-strand breaks generated during meiosis I. Adapted from Molecular Biology of the Cell, 6th Edition (Alberts et al.) "],["setup.html", "3.3 Setup", " 3.3 Setup In this module, we’ll use sequencing data from families to look at the relationship between DNMs, crossovers, and parental age. 3.3.1 R packages We’re using R’s tidyverse library to analyze our data. You can load this R package by running: library(tidyverse) 3.3.2 Data Our data comes from the supplementary tables of this paper by Halldorsson et al., which performed whole-genome sequencing on “trios” (two parents and one child) in Iceland. We’ve pre-processed the data to make it easier to work with. Load the pre-processed data by running the code chunk below. # read data dnm_by_age <- read.table("dnm_by_age_tidy_Halldorsson.tsv", sep = "\\t", header = TRUE) # preview data head(dnm_by_age) ## Proband_id n_paternal_dnm n_maternal_dnm n_na_dnm Father_age Mother_age ## 1 675 51 19 0 31 36 ## 2 1097 26 12 1 19 19 ## 3 1230 42 12 3 30 28 ## 4 1481 53 14 1 32 20 ## 5 1806 61 11 6 38 34 ## 6 2280 63 9 3 38 20 The columns in this table are: Proband_id: ID of the child (i.e., “proband”) n_paternal_dnm: Number of DNMs (carried by the child) that came from the father n_maternal_dnm: Number of DNMs that came from the mother n_na_dnm: Number of DNMs whose parental origin can’t be determined Father_age: Father’s age at proband’s birth Mother_age: Mother’s age at proband’s birth "],["visualizing-the-data.html", "3.4 Visualizing the data", " 3.4 Visualizing the data We can use our tidied data to ask questions about the de novo mutation rate in these Icelandic individuals. How does parental age affect the number of DNMs for males and females? Use the dnm_by_age data to plot this relationship for males. ggplot(data = dnm_by_age, # specify where ggplot should be getting the x location for each data point aes(x = Father_age, # specify where ggplot should be getting the y location for each data point y = n_paternal_dnm)) + # specify that the data should be plotted as points geom_point() Based on your plot, would you say that there’s an association between paternal age and number of DNMs? It looks like there’s a pretty strong association between paternal age and number of DNMs, where older males have more DNMs. Modify your code to plot the relationship between age and number of DNMs for females. Does there seem to be an association between maternal age and number of DNMs? ggplot(data = dnm_by_age, aes(x = Mother_age, y = n_maternal_dnm)) + geom_point() There’s also a strong positive association between maternal age and number of DNMs, although the slope (i.e., the increase in number of DNMs per year) is shallower. "],["linear-models.html", "3.5 Linear models", " 3.5 Linear models We can visually observe that age seems associated with number of DNMs in both males and females, but we need a way to ask if that this is a statistically meaningful association. We can do this with a linear model. This model fits a line to the plots that we just made, and asks if the slope is significantly different from 0 (i.e., if there’s a significant increase in DNM count as age increases). If this is a statistical test, what’s the null hypothesis? The null hypothesis for this linear model is that the slope is 0 – i.e., that there’s no association between parental age and the number of DNMs from that parent. If the slope is significantly different from 0, we can reject the null hypothesis. We’ll fit a linear model using R’s lm function. Run the following code block to open a manual describing the function. ?lm lm requires two arguments: The formula or equation it’s evaluating A table of data The formula must be in the format response variable ~ predictor variable(s), where each variable is the name of a column in our data table. Is our predictor variable the parental age or the number of DNMs? The predictor variable is parental age. We expect the number of DNMs to change as a consequence of parental age. "],["fitting-a-linear-model-for-dnms.html", "3.6 Fitting a linear model for DNMs", " 3.6 Fitting a linear model for DNMs Run the following code to fit a model for the effect of age on paternal DNMs. # fit linear model for paternal DNMs fit_pat <- lm(formula = n_paternal_dnm ~ Father_age, data = dnm_by_age) # print results of model summary(fit_pat) ## ## Call: ## lm(formula = n_paternal_dnm ~ Father_age, data = dnm_by_age) ## ## Residuals: ## Min 1Q Median 3Q Max ## -32.785 -5.683 -0.581 5.071 31.639 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 10.58819 1.70402 6.214 1.34e-09 *** ## Father_age 1.34849 0.05359 25.161 < 2e-16 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 8.426 on 388 degrees of freedom ## Multiple R-squared: 0.62, Adjusted R-squared: 0.619 ## F-statistic: 633.1 on 1 and 388 DF, p-value: < 2.2e-16 How do you interpret results from a linear model? For our purposes, the only part of the results you need to look at is the line under (Intercept) in the Coefficients section: Estimate Std. Error t value Pr(>|t|) Father_age 1.34849 0.05359 25.161 < 2e-16 *** The fourth columm, Pr(>|t|), is the p-value. Because this p-value is < 2e-16, we can reject the null hypothesis and say that there is association between paternal age and the number of paternal DNMs. The first column, Estimate, is the slope, or coefficient. Linear regression fits a line to our plot of paternal age vs. number of DNMs. The coefficient estimate is the slope of that line. The slope for paternal age given by this linear model is 1.34849. We can interpret this number this way: For every additional year of paternal age, we expect 1.35 additional paternal DNMs in the child. Modify your code to assess the relationship between maternal age and number of maternal DNMs. Is this relationship significant? How many maternal DNMs do we expect for every additional year of maternal age? # fit linear model for maternal DNMs fit_mat <- lm(formula = n_maternal_dnm ~ Mother_age, data = dnm_by_age) # print results of model summary(fit_mat) ## ## Call: ## lm(formula = n_maternal_dnm ~ Mother_age, data = dnm_by_age) ## ## Residuals: ## Min 1Q Median 3Q Max ## -9.8683 -3.1044 -0.2329 2.2394 17.5379 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 2.51442 0.98193 2.561 0.0108 * ## Mother_age 0.37846 0.03509 10.785 <2e-16 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 4.503 on 388 degrees of freedom ## Multiple R-squared: 0.2307, Adjusted R-squared: 0.2287 ## F-statistic: 116.3 on 1 and 388 DF, p-value: < 2.2e-16 The p-value is <2e-16 and the Mother_age slope is 0.37846. This relationship is significant, and we expect 0.38 more maternal DNMs for every additional year of maternal age. "],["confidence-intervals.html", "3.7 Confidence intervals", " 3.7 Confidence intervals Our models predict that there are 1.35 more DNMs for additional every year of paternal age, and 0.38 more DNMs for every additional year of maternal age. Does this mean that sperm and oocytes accumulate DNMs at different rates? The maternal and paternal slopes look different, but we need statistical evidence that they actually are. (For example, what if there’s a lot of variability in the maternal DNM data, and the true maternal coefficient could be anywhere between -1 and 10?) To do this, we compare the confidence intervals of our slope estimates. What is a confidence interval? We use confidence intervals when estimating a value – in this case, the Mother_age and Father_age slope parameters. A confidence interval (CI) is a random interval that has a 95% probability of falling on the parameter we are estimating. So, a 95% CI contains the true value of the slope 95% of the time. Keep in mind that the definition above (95% of random intervals fall on the true value) is not the same as saying there is a 95% chance that the true value falls within our interval. This latter statement is not accurate. In R, we get the confidence interval of a parameter from a linear model with the confint function. ?confint confint requires three arguments: A fitted linear model (our fit_pat variable) The parameter we want a CI for (Father_age) The CI’s probability (typically 95%) "],["calculate-95-cis.html", "3.8 Calculate 95% CIs", " 3.8 Calculate 95% CIs Run the following code to calculate the 95% confidence interval for the Father_age slope parameter. confint(fit_pat, 'Father_age', level = 0.95) ## 2.5 % 97.5 % ## Father_age 1.243118 1.45386 So, 95% of the time, the number of additional DNMs per year of paternal age is between 1.24 and 1.45. Modify your code to get the 95% CI for the Mother_age slope. What’s the interpretation of this confidence interval? confint(fit_mat, 'Mother_age', level = 0.95) ## 2.5 % 97.5 % ## Mother_age 0.3094713 0.4474528 95% of the time, the number of additional DNMs per year of maternal age is between 0.31 and 0.45. Now that we have the confidence intervals for both slope parameters, we can finally compare them. Our two CI ranges are non-overlapping. The paternal range is [1.24, 1.45] and the maternal range is [0.31, 0.45]. If the 95% CIs for two parameters don’t overlap, this strongly supports that the parameters are significantly different from one another. So, it seems likely that paternal and maternal gametes experience different rates of de novo mutation. If the CIs for two parameters overlap, are they not significantly different? Not necessarily. More analysis, like a hypothesis test, is needed to make a final decision. "],["conclusion-1.html", "3.9 Conclusion", " 3.9 Conclusion In this lab, we explored the relationship between parental age and the number of de novo mutations in their gametes. We plotted the relationship between maternal/paternal age and DNM count. This visualization suggested that DNM count increases with age for both groups. We confirmed this hypothesis by using a linear model, which tests if additional years of age have a non-zero effect on the number of DNMs. The number of paternal DNMs seemed to increase more quickly with age than maternal DNMs. We confirmed this by comparing the 95% confidence intervals of the slopes of the two models. One final question – let’s assume that there really is a difference between the effect of age on DNMs in male and female gametes. What biological reasons might be causing this difference? "],["homework-1.html", "3.10 Homework", " 3.10 Homework So far, we’ve only looked at the de novo mutation data from the Halldorsson et al. paper. Now we’ll use their data on the number of maternal and paternal origin crossovers (i.e., how many crossovers occurred across all chromosomes in the maternal and paternal gametes). 3.10.0.1 Learning Objectives Practice visualizing data with ggplot2 Interpret p-values and effect sizes from linear models "],["required-homework.html", "3.11 Required homework", " 3.11 Required homework The data from the paper has been pre-filtered for you. Run this code block to read it in: # read data crossovers <- read.table("crossovers.tsv", header = TRUE) # preview data head(crossovers) ## Proband_id n_pat_xover n_mat_xover Father_age Mother_age ## 1 3 22 51 29 28 ## 2 10 26 50 26 26 ## 3 11 25 38 25 22 ## 4 15 24 50 31 26 ## 5 20 27 35 26 24 ## 6 22 28 40 39 31 The columns in this table are: Proband_id: ID of the child n_pat_xover: Number of crossovers (carried by the child) that occurred in the paternal gametes n_mat_xover: Number of crossovers that occurred in the maternal gametes Father_age: Father’s age at proband’s birth Mother_age: Mother’s age at proband’s birth Assignment: Using the ggplot code from this module, plot the relationship between parental age and number of crossovers. As with the DNM data, make one plot for the maternal crossovers and one plot for the paternal. Do you think parental age impacts crossover number? Solution Plot paternal crossovers: ggplot(data = crossovers, # x axis is paternal age aes(x = Father_age, # y axis is number of crossovers y = n_pat_xover)) + geom_point() Plot maternal crossovers: ggplot(data = crossovers, # x axis is maternal age aes(x = Mother_age, # y axis is number of crossovers y = n_mat_xover)) + geom_point() Just by eye, it doesn’t really seem that age affects number of crossovers for either mothers or fathers. "],["optional-homework.html", "3.12 Optional homework", " 3.12 Optional homework Assignment: Fit two linear models (one paternal, one maternal) to ask if there is an association between the number of parental crossovers and parental age. If there is an association, how is the number of crossovers predicted to change with every year of maternal/paternal age? Solution # fit the model with paternal age fit_pat <- lm(data = crossovers, formula = n_pat_xover ~ Father_age) summary(fit_pat) ## ## Call: ## lm(formula = n_pat_xover ~ Father_age, data = crossovers) ## ## Residuals: ## Min 1Q Median 3Q Max ## -15.2173 -3.1880 -0.1997 2.8061 24.7652 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 26.369432 0.102736 256.67 <2e-16 *** ## Father_age -0.005852 0.003462 -1.69 0.091 . ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 4.388 on 41090 degrees of freedom ## Multiple R-squared: 6.953e-05, Adjusted R-squared: 4.519e-05 ## F-statistic: 2.857 on 1 and 41090 DF, p-value: 0.09098 There isn’t a significant association between paternal age and the number of paternal crossovers (p = 0.091). # fit the model with maternal age fit_mat <- lm(data = crossovers, formula = n_mat_xover ~ Mother_age) summary(fit_mat) ## ## Call: ## lm(formula = n_mat_xover ~ Mother_age, data = crossovers) ## ## Residuals: ## Min 1Q Median 3Q Max ## -27.161 -6.095 -0.425 5.641 45.905 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 41.709271 0.206238 202.24 <2e-16 *** ## Mother_age 0.065989 0.007576 8.71 <2e-16 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 8.685 on 41090 degrees of freedom ## Multiple R-squared: 0.001843, Adjusted R-squared: 0.001819 ## F-statistic: 75.87 on 1 and 41090 DF, p-value: < 2.2e-16 Surprisingly, there is a significant association between maternal age and the number of maternal crossovers (p < 2e-16). For every year of maternal age, we expect the child to carry 0.07 additional maternal origin crossovers. Although the maternal crossovers plot doesn’t look that impressive, our estimated slope is 0.07, which is probably too small to distinguish visually. "],["linkage-disequilibrium.html", "4 Linkage disequilibrium", " 4 Linkage disequilibrium In this module, we’ll use DNA sequencing data from human populations to assess linkage disequilibrium between two genetic variants. 4.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Define linkage disequilibrium. Manually calculate \\(D\\), \\(D'\\), and \\(r^2\\) from genotype data. Understand the differences in interpretation for different LD statistics. Explain how LD both benefits and limits genetics studies. "],["what-is-linkage-disequilibrium.html", "4.1 What is linkage disequilibrium?", " 4.1 What is linkage disequilibrium? Linkage disequlibrium (LD) refers to correlation among genotypes at multiple sites in the genome. This is a consequence of the fact that chromosomes are transmitted in “chunks” through the generations. When mutations arise, they arise on a single chromosome with a given set of alleles. The new mutation will continue to be associated with this genetic background until it is shuffled during the process of meiotic recombination. Together, a set of alleles that tend to occur together because of linkage disequilibrium is called a haplotype. Fig. 1. After a new mutation arises, recombination over the course of many generations reduces the number of variants in LD with it. "],["why-do-we-care-about-ld.html", "4.2 Why do we care about LD?", " 4.2 Why do we care about LD? As a result of linkage disequilibrium, knowledge of a genotype at one site in the genome can provide information about the genotype at another site, even if the second site was not actually genotyped. Using prior knowledge of LD to “fill in” missing genotype information is a process called imputation. Linkage disequilibrium also means that correlation between a genotype at a particular site and phenotype (e.g., disease outcome) does not imply causation. Even ignoring other possible confounders, any variant on the same haplotype could be driving the association. Beyond mutation and recombination, other evolutionary forces such as gene flow, genetic drift, and natural selection can also influence patterns of LD observed in population genetic data. Measuring linkage disequilibrium is therefore important for both medical and evolutionary studies. Fig. 2. LD can be used to impute missing genotypes, but also complicates genetic association studies (such as finding variants that cause disease). Non-causal variants in LD will perfectly co-occur with the causal variant, making it difficult to determine which one is truly causal. "],["setup-1.html", "4.3 Setup", " 4.3 Setup We’ll measure LD between two SNPs called in the 1000 Genomes Project dataset: rs28574812 (chr21:15012619) rs2251399 (chr21:15013185) We’ve preprocessed the original 1000 Genomes data such that every line in the table below represents one haplotype in the 1000 Genomes database. Load the pre-processed data by running the code below. # read data haplotypes <- read.table("snp_haplotypes.txt", header = TRUE) # preview data head(haplotypes) ## sample haplotype snp1_allele snp2_allele ## 1 HG00096 hap_1 A C ## 2 HG00096 hap_2 A C ## 3 HG00097 hap_1 A C ## 4 HG00097 hap_2 A C ## 5 HG00099 hap_1 A C ## 6 HG00099 hap_2 A C The columns in this table are: sample: Name of the individual who was sequenced haplotype: Haplotype (i.e., the maternal or paternal chromosome) that the SNP is on snp1_allele: Genotype at SNP1 on this haplotype snp2_allele: Genotype at SNP2 on this haplotype Note that there are 2,504 samples in the 1000 Genomes Project but 5,008 total lines in the table. This is because there are two lines per individual – one for each of their maternal and paternal haplotypes. Fig. 3. Our reformatted VCF shows the combinations of alleles at two SNPs of interest, for all haplotypes in the 1000 Genomes dataset. "],["are-these-snps-in-ld.html", "4.4 Are these SNPs in LD?", " 4.4 Are these SNPs in LD? If we run table on each SNP column, we can see which alleles exist at SNP1 and SNP2. SNP1 can be A or G SNP2 can be C or T table(haplotypes$snp1_allele) ## ## A G ## 3456 1552 table(haplotypes$snp2_allele) ## ## C T ## 2825 2183 If these two SNPs were in perfect LD, we’d expect to see only two haplotypes in our data (Fig. 4A). A C: If someone carries an A at SNP1, they will always carry a C at SNP2. G T: If they carry a G at SNP1, they will always carry a T at SNP2. If these two SNPs were in linkage equilibrium, the allele at SNP1 would give us no information about SNP2. We would expect to see all four possible haplotypes, in amounts proportional to the component allele frequencies (Fig. 4B). A C A T G C G T Fig. 4. When two SNPs are in perfect LD, seeing an allele on one haplotype perfectly predicts which allele is on the other haplotype. "],["counting-haplotypes-with-table.html", "4.5 Counting haplotypes with table", " 4.5 Counting haplotypes with table We can use the table function to count the occurrence of the four possible haplotypes. table(haplotypes$snp1_allele, haplotypes$snp2_allele) ## ## C T ## A 2655 801 ## G 170 1382 The table tells us that there are 2655 A C haplotypes (A at SNP1 and C at SNP2), 170 G C haplotypes, etc. Do these SNPs look like they’re in LD? It looks like there are some haplotypes (A C and G T) that are overrepresented. However, it’s hard to tell whether that’s just because an A allele at SNP1 is much more common than T is. "],["fishers-exact-test.html", "4.6 Fisher’s exact test", " 4.6 Fisher’s exact test We can wrap our table in the fisher.test function to perform a Fisher’s exact test. This test tells us whether there is a non-random association between any of the SNP alleles, while accounting for the relative proportions of each allele. fisher.test(table(haplotypes$snp1_allele, haplotypes$snp2_allele)) ## ## Fisher's Exact Test for Count Data ## ## data: table(haplotypes$snp1_allele, haplotypes$snp2_allele) ## p-value < 2.2e-16 ## alternative hypothesis: true odds ratio is not equal to 1 ## 95 percent confidence interval: ## 22.49760 32.33934 ## sample estimates: ## odds ratio ## 26.9124 The p-value is very small (< 2.2e-16), so we can reject the null hypothesis that the two SNPs are associating independently of each other. How do we interpret the odds ratio from the Fisher’s exact test? In addition to the p-value, Fisher’s Exact Test also gives us an odds ratio of 26.9, with a 95% confidence interval of [22.5, 32.3]. In this context, the odds ratio reflects how much more likely you are to see an A at SNP1 if you also see an C at SNP2. We can observe that the 95% confidence interval doesn’t overlap with 1. An odds ratio of 1 would mean that seeing C at SNP2 doesn’t influence the probability of seeing an A at SNP1. This is a somewhat non-canonical usage of Fisher’s exact test, and in our case the odds ratio applies to whatever haplotype is in the top left corner of our 4x4 table. We could rearrange the table to calculate the odds ratio for any of the three other combinations of alleles. Together, the p-value and 95% confidence interval tell us that there is strong evidence of LD between these SNPs. Perhaps this isn’t surprising, since our two SNPs are common and close to one another on chromosome 21. "],["measuring-ld-with-d.html", "4.7 Measuring LD with \\(D\\)", " 4.7 Measuring LD with \\(D\\) If SNP1 and SNP2 are in linkage equilibrium, the probability of seeing an A C haplotype should be equal to the product of the allele frequencies of A and C. This is simply the probablity of observing two events together if the events are independent. Otherwise, for SNPs that are not independent of each other, we should see A C either more or less often than expected from the allele frequencies. This intuition is summarized in \\(\\mathbf{D}\\), a population genetics statistic for measuring LD between two SNPs. \\[ D = h_{12} - p_1*p_2 \\] \\(\\mathbf{h_{12}}\\) is the frequency of our haplotype of interest (A C). \\(\\mathbf{p_1*p_2}\\) is the product of the frequencies of the two alleles on this haplotype (A at SNP1 and C at SNP2) How do we interpret \\(D\\)? If two SNPs are in linkage equilibrium, \\(h_{12}\\) and \\(p_1*p_2\\) should be the same, and we should get \\(D = 0\\). If two SNPs are in linkage disequilibrium, \\(p_1*p_2\\) should be different from \\(h_{12}\\), so that \\(D \\neq 0\\). "],["calculating-d.html", "4.8 Calculating \\(D\\)", " 4.8 Calculating \\(D\\) We can re-run our table code to find the probabilities we need for calculating \\(D\\). table(haplotypes$snp1_allele, haplotypes$snp2_allele) ## ## C T ## A 2655 801 ## G 170 1382 \\[ D = h_{12} - p_1*p_2 \\] What are \\(h_{12}\\), \\(p_1\\), and \\(p_2\\)? \\(h_{12}\\) is the probability of seeing the A C haplotype. This is equal to the number of A C haplotypes over the number of total haplotypes: \\[\\frac{2655}{2655 + 170 + 801 + 1382} = \\frac{2655}{5008}\\] \\(p_1\\) is the probability that SNP1 is A. We can get this by adding across the first row of the table (i.e., adding the number of A C and A T haplotypes): \\[\\frac{2655 + 801}{5008}\\] \\(p_2\\) is the probability that SNP2 is C. We can get this by adding across the first column of the table (i.e., adding the number of A C and G G haplotypes): \\[\\frac{2655 + 170}{5008}\\] (Note that the denominator is always 5008 – the total number of haplotypes in our dataframe.) Now we can plug in the corresponding probabilities to calculate D: # define our probabilities of interest h <- 2655 / 5008 p1 <- (2655 + 801) / 5008 p2 <- (2655 + 170) / 5008 # calculate D D <- h - (p1 * p2) D ## [1] 0.1408705 \\(D = 0.14\\), which is non-zero, suggesting that these SNPs are in LD. "],["measuring-ld-with-d-1.html", "4.9 Measuring LD with \\(D'\\)", " 4.9 Measuring LD with \\(D'\\) Aside from being nonzero, what does the value of \\(D\\) mean? This is surprisingly hard to interpret because the minimum and maximum value of \\(D\\) is different for every pair of SNPs. Why does the range of \\(D\\) change? The possible values of \\(D\\) depend on the frequencies of the alleles at each SNP. For example: If \\(p_1 = 0.5\\) and \\(p_2 = 0.5\\), then \\(D\\) is between \\([-0.25, 0.25]\\) If \\(p_1 = 0.1\\) and \\(p_2 = 0.7\\), then \\(D\\) is between \\([-0.07, 0.03]\\) The \\(\\mathbf{D'}\\) statistic fixes this issue by dividing \\(D\\) by its theoretical maximum. \\(D'\\) is constrained between \\([-1, 1]\\), where more extreme values denote stronger LD. \\[ D' = \\frac{D}{\\mathrm{max}(-p_1 p_2, -(1-p_1)(1-p_2))}, \\mathrm{\\:for\\:} D < 0 \\\\ D' = \\frac{D}{\\mathrm{min}(p_1 (1-p_2), p_2(1-p_1) )}, \\mathrm{\\:for\\:} D > 0 \\] \\(p_1\\) and \\(p_2\\) are the frequencies of the alleles at SNP1 and SNP2. Use this formula to calculate \\(D'\\) for our two SNPs of interest. Because \\(D\\) is positive, we use the second formula for \\(D'\\). First, we need to find the denominator, which is the minimum of \\(p_1 (1-p_2)\\) and \\(p_2 (1-p_1)\\). p1 * (1-p2) ## [1] 0.3008145 p2 * (1-p1) ## [1] 0.1748161 p2 * (1-p1) is smaller, so we plug that into our \\(D'\\) formula: Dprime <- D / (p2 * (1-p1)) Dprime ## [1] 0.8058206 This tells us that LD between these two SNPs is 80.6% of its theoretical maximum. "],["measuring-ld-with-r2.html", "4.10 Measuring LD with \\(r^2\\)", " 4.10 Measuring LD with \\(r^2\\) \\(\\mathbf{r^2}\\) is the most common statistic for measuring LD. Its value ranges from [0, 1], where 1 indicates maximum LD. \\[ r^2 = \\frac{D^2}{p_1 (1-p_1) p_2 (1-p_2)} \\] Although it looks similar to the formulas for \\(D\\) and \\(D'\\), \\(r^2\\) is actually derived from the correlation coefficient of the frequencies of SNP1 and SNP2, and has a slightly different interpretation: \\(D\\) and \\(D'\\) measure whether recombination has occurred between two alleles \\(r^2\\) measures how well we can predict the allele at one locus if given the allele at the other locus Calculate \\(r^2\\) for our two SNPs of interest. r2 <- D^2 / (p1*(1-p1)*p2*(1-p2)) r2 ## [1] 0.3773631 \\(r^2 = 0.38\\), indicating that these SNPs are in moderate LD. "],["ldlink.html", "4.11 LDlink", " 4.11 LDlink LDlink is a web application that allows you to compute and visualize linkage disequilibrium using data from the 1000 Genomes Project (the same dataset we’ve been using for this module). Go to LDlink’s LDpair tool, which computes \\(D'\\) and \\(r^2\\) between pairs of SNPs. Using either the rsIDs or the chromosome and position of the two SNPs we looked at today, check our calculations for \\(D'\\) and \\(r^2\\). Make sure you: Select All Populations, since we didn’t subset our data by population. If using SNP position, note that our data was aligned to the GRCh38 reference genome. Fig. 5. LDpair results for the two SNPs from this class. We can see that these \\(D'\\) and \\(r^2\\) statistics, as well as the 4x4 table, are very similar to what we calculated by hand! (The values aren’t identical because we’re using a slightly different genotyping dataset.) "],["visualizing-ld-blocks.html", "4.12 Visualizing LD blocks", " 4.12 Visualizing LD blocks LDproxy, another LDlink tool, finds all SNPs in strong LD with a SNP of interest. Open LDproxy and use it to search for one of the SNPs from today (it may take the webpage a minute to load the results). Fig. 6. LDproxy results for rs28574812. To generate this plot, LDproxy calculated \\(r^2\\) between our SNP of interest and all other SNPs in a 500kb window. As expected, we can see that LD is strongest for variants that are closest to the SNP. LDproxy also provides even more information than just LD – it also includes regulatory annotations for all the variants in this region (the numbers within each dot), as well as gene annotations and a list of nearby variants (below the plot). "],["ld-in-association-studies.html", "4.13 LD in association studies", " 4.13 LD in association studies The figure below is a locuszoom plot – a common visualization of data from genome-wide association studies (GWAS). This particular study was a GWAS for genetic variants that impact mean corpuscular hemoglobin concentration. The left y-axis is the p-value for the association with mean corpuscular hemoglobin concentration Each variant is colored by its \\(\\mathbf{r^2}\\) with the top hit variant (in purple) The heatmap on the bottom shows pairwise LD between variants The right y-axis and dark blue line show the frequency of recombination events. Peaks are recombination hotspots (note how they line up with the boundaries of LD blocks in the heatmap) We can observe a block of red/orange variants with almost the same p-value as the top hit. All of these variants are in strong LD with each other: all of them except the leftmost cluster fall within the same LD block in the heatmap on the bottom. As a result, any of them could be causal – i.e., the one that actually affects corpuscular hemoglobin. This is a problem that affects all association studies. Two common ways of working around LD to identify causal variants are: Statistical fine mapping: Uses patterns of LD and statistical models to narrow down casual variant sets Experimental screening: Tests candidate variants in vitro (ex: massively parallel reporter assays, CRISPR screens) to determine which have functional effects Fig. 7. GWAS associations with mean corpuscular hemoglobin concentration, from this paper. "],["conclusion-2.html", "4.14 Conclusion", " 4.14 Conclusion In this lab, we used genotype data from the 1000 Genomes Project to ask whether there is linkage disequilibrium between two SNPs on chr21. Using data from the VCF, we used table to count how often we observe combinations of alleles at these SNPs. We used the data in the table to calculate three LD statistics: \\(\\mathbf{D}\\): the deviation of the observed haplotype frequency from the expected haplotype frequency \\(\\mathbf{D'}\\): a normalization of \\(D\\) that ranges from \\([-1, 1]\\) \\(\\mathbf{r^2}\\): how well the allele at one locus predicts the allele at another locus We used LDlink to visualize how blocks of LD define haplotypes. "],["homework-2.html", "4.15 Homework", " 4.15 Homework 4.15.0.1 Learning Objectives Calculate and interpret LD statistics 4.15.0.2 Assignment We’ve subset the VCF from class to show haplotypes for two different pair of SNPs: chr21:15005329 and chr21:15007704 chr21:15336586 and chr21:15336794 # read data for first set of SNPs hw1 <- read.table("snp_haplotypes_hw1.txt", header = TRUE) # read data for second set of SNPs hw2 <- read.table("snp_haplotypes_hw2.txt", header = TRUE) Assignment: Using the code from class, calculate \\(D\\), \\(D'\\), and \\(r^2\\) for these sets of SNPs. Which alleles are segregating together? What does each LD statistic indicate? (Feel free to check your work on LDpair.) Solution for first set of SNPs First use table to count the occurences of the four haplotypes. table(hw1$snp1_allele, hw1$snp2_allele) ## ## A G ## C 747 2508 ## T 2 1751 All four possible haplotypes exist in this population. \\(\\mathbf{D = h_{12} - p_1*p_2}\\) h <- 747 / 5008 p1 <- (747 + 2508)/5008 p2 <- (747 + 2)/5008 D <- h - p1 * p2 D ## [1] 0.05195286 \\(D\\) is non-zero, which suggests that these SNPs might be in LD. \\(\\mathbf{D' = \\frac{D}{\\mathrm{min}(p_1 (1-p_2), p_2(1-p_1))}}\\) (because \\(D > 0\\)) First we determine the denominator by calculating which of \\(p_1 (1-p_2)\\) and \\(p_2(1-p_1)\\) is smaller: p1 * (1-p2) ## [1] 0.5527516 p2 * (1-p1) ## [1] 0.05235222 \\(p_2(1-p_1)\\) is smaller, so we use it for the denominator. \\(D'\\) is: Dprime <- D / ((1-p1) * p2) Dprime ## [1] 0.9923717 \\(D' = 0.99\\), which indicates very high LD (almost no recombination has occurred between alleles on this haplotype). \\(\\mathbf{r^2 = \\frac{D^2}{p_1 (1-p_1) q_1 (1-q_1)}}\\) r2 <- D^2 / (p1 * (1-p1) * p2 * (1-p2)) r2 ## [1] 0.09327254 However, \\(r^2 = 0.09\\) (linkage equilibrium)! This is because one of the haplotypes, A T, is very rare – there are only two copies in the population. \\(r^2\\) tells us that the counts of the A T haplotype are so low that an A at SNP1 doesn’t do a great job of predicting when SNP2 is T. Solution for second set of SNPs First use table to count the occurences of the four haplotypes. table(hw2$snp1_allele, hw2$snp2_allele) ## ## A G ## A 3522 0 ## G 0 1486 The only haplotypes that exist in this population are A C and G G. \\(\\mathbf{D = h_{12} - p_1*p_2}\\) h <- 3522 / 5008 p1 <- (3522 + 0)/5008 p2 <- (3522 + 0)/5008 D <- h - p1 * p2 D ## [1] 0.2086794 \\(D\\) is non-zero, which suggests that these SNPs might be in LD. \\(\\mathbf{D' = \\frac{D}{\\mathrm{min}(p_1 (1-q_1), (1-p_1)q_1 )}}\\) (because \\(D > 0\\)) First we determine the denominator by calculating which of \\(p_1 (1-p_1)\\) and \\(p_2 (1-p_2)\\) is smaller: p1 * (1-p2) ## [1] 0.2086794 p2 * (1-p1) ## [1] 0.2086794 The two values are exactly the same, so we can use either for the denominator. \\(D'\\) is: Dprime <- D / (p1 * (1-p2)) Dprime ## [1] 1 \\(D' = 1\\)! These SNPs are in maximum LD (no recombination has occured between them). \\(\\mathbf{r^2 = \\frac{D^2}{p_1 (1-p_1) p_2 (1-p_2)}}\\) r2 <- D^2 / (p1 * (1-p1) * p2 * (1-p2)) r2 ## [1] 1 \\(r^2 = 1\\)! These SNPs are in maximum LD (everyone who carries an A at SNP1 has an A at SNP2, and everyone with a G at SNP1 has a G at SNP2). "],["simulating-evolution.html", "5 Simulating evolution", " 5 Simulating evolution In this lab, we’ll build a simulation to explore genetic drift using the Wright-Fisher model. 5.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Describe the phenomenon of genetic drift. Explain why random draws from a binomial distribution are a good way to mimic the effect of drift. Interpret allele frequency patterns that occur as a result of drift. Write a for loop in R. Write a function to run code multiple times with different parameters. "],["genetic-drift.html", "5.1 Genetic drift", " 5.1 Genetic drift In all populations, genetic drift acts to change allele frequencies over time. Drift refers to random changes in an allele’s frequency between generations. These random changes occur because individuals carrying different alleles will have different numbers of offspring due to chance. Fig. 1 (source). An allele’s frequency “drifts” between generations due to random chance. Drift differs from selection, which is a deterministic (non-random) change in an allele’s frequency. If an allele is under selection, it’s more likely to increase or decrease in frequency depending on whether it is beneficial or deleterious. Genetic drift, on the other hand, cannot consistently cause an allele’s frequency to increase or decrease. "],["the-wright-fisher-model.html", "5.2 The Wright-Fisher model", " 5.2 The Wright-Fisher model The Wright-Fisher model is one of the most commonly used models of genetic drift. In this model, we assume that a population: Mates randomly Number of individuals remains constant between generations Today, we’ll also assume that the population is haploid Populations in the real world don’t behave like an ideal Wright-Fisher population, so their effective population size Ne is usually much smaller than their actual population size. The effective population size of the human population is only 12,800–14,400 individuals, even though its actual size is around 8 billion. "],["allele-frequency-fixation-and-loss.html", "5.3 Allele frequency, fixation, and loss", " 5.3 Allele frequency, fixation, and loss The Wright-Fisher model describes the behavior of a single allele, which can be at any variable site in a population (a SNP, insertion/deletion, version of a gene, etc.). The allele of interest begins the simulation at some initial allele frequency (AF). This allele frequency is the proportion of individuals in the population who carry that allele, and is always between 0 and 1. An allele becomes fixed in a population if it reaches an allele frequency of 1, and is lost if it reaches a frequency of 0. At either of these points, it is no longer considered a variable site because either everyone or no one in the population carries it. Fig. 2 (source). Trajectories of alleles at two loci fixing, at AF = 0 and AF = 1. "],["modeling-allele-frequencies.html", "5.4 Modeling allele frequencies", " 5.4 Modeling allele frequencies In the Wright-Fisher model, we track a population over the course of many generations. Within each generation: For every individual, we perform a coin flip to determine whether or not they have the allele. Unlike a coin, the probability of receiving an allele is equal to its allele frequency in the current generation. The more common an allele is in this generation, the more likely it is that someone in the next generation will also carry it. After flipping these coins, we know the number of people in the next generation who carry the allele. Fig. 3. Every individual flips a weighted coin to determine whether they will carry the blue allele in the next generation. The probability of carrying the allele is equal to the allele’s frequency in the current generation. "],["the-binomial-distribution.html", "5.5 The binomial distribution", " 5.5 The binomial distribution Instead of having to actually simulate all the coin flips, we can get the number of allele carriers by performing a single draw from a binomial distribution with size N (# of individual) and success probability p = AF. This distribution tells you how many successes you expect to see from a set of N independent coin flips. If we try to draw 100,000 times from a binomial distribution with population size 100 and success probability (AF) 0.5, it will look something like this: Figure 5.1: 100,000 draws from a binomial distribution. The majority of the distribution lies between 48 and 52. Just as we expect based on the allele frequency, the next generation will most likely have around 48-52 individuals with the A allele. But because this is a random draw, there’s a small chance that we might end up with many more or many fewer than that number. "],["setup-2.html", "5.6 Setup", " 5.6 Setup 5.6.1 R packages library(tidyverse) 5.6.2 Data We’ll simulate all of our own data for this lab! "],["the-rbinom-function.html", "5.7 The rbinom function", " 5.7 The rbinom function The basis of our simulation is R’s rbinom function, which allows us to sample from a binomial distribution. rbinom takes three arguments: n: how many times we’re drawing from the distribution size: the size of the population we’re sampling from (i.e. N) p: the success probability (i.e. allele frequency) Every generation, we’ll draw once to produce the number of individuals carrying the A allele in the next generation. Let’s once again look at a population of size 100, and an A allele currently at AF = 0.5. We use rbinom to get the number of individuals in the next generation who will have A: rbinom(n = 1, size = 100, prob = 0.5) ## [1] 45 Change the rbinom code so that it returns the allele frequency (instead of the number of individuals). # divide by the population size to get AF rbinom(n = 1, size = 100, prob = 0.5) / 100 ## [1] 0.51 Why do we get a different number every time we run rbinom? rbinom generates a random number between 0 and 100. Because it’s random, the number it draws will be different every time we run it. "],["increasing-population-size.html", "5.8 Increasing population size", " 5.8 Increasing population size Currently, we’re drawing from a population of 100 individuals. Now let’s see what happens when we increase the population size. (Feel free to run this code block multiple times!) rbinom(n = 1, size = 10000, prob = 0.5) / 10000 ## [1] 0.4934 If you run the code block above multiple times, you’ll observe that the AF is much closer to 0.5 than it was with a population of size 100. This lends to our intuition that an allele’s frequency fluctuates much more when a population is small, and is more stable when the population size is large. How does population size affect an allele’s time to fixation? As population size gets larger, the allele will take longer to fix. "],["simulating-multiple-generations.html", "5.9 Simulating multiple generations", " 5.9 Simulating multiple generations Currently, we draw once from a binomial distribution to get the number of individuals in one generation who carry the allele of interest. How do we adapt this to simulate multiple generations? Increasing n (ex: rbinom(n = 10, size = 100, prob = 0.5)) Increasing n only gives you multiple replicate draws from the same distribution. This doesn’t reflect multiple generations, because the allele frequency doesn’t update between generations based on the new number of alleles – it uses prob = 0.5 every time. "],["for-loops.html", "5.10 For loops", " 5.10 For loops Instead of drawing multiple times from the same distribution, we can write a for loop to repeatedly generate and update the number of individuals with the A allele. A for loop allows you to run some code X number of times. For example: for (i in 1:3) { print(i) } ## [1] 1 ## [1] 2 ## [1] 3 This for loop goes through all the values between 1 and 3, and prints each of them out. Modify the for loop to instead run our rbinom command. for (i in 1:3) { print(rbinom(n = 1, size = 100, prob = 0.5) / 100) } ## [1] 0.49 ## [1] 0.45 ## [1] 0.43 "],["updating-variables-within-a-for-loop.html", "5.11 Updating variables within a for loop", " 5.11 Updating variables within a for loop We also need to update the allele frequency in every iteration of the for loop. We do this by adding a freq variable that keeps track of the current AF: # start an initial AF of 0.5 freq <- 0.5 for (i in 1:3) { # run rbinom to generate the AF for the next generation new_freq <- rbinom(n = 1, size = 100, prob = freq) / 100 # print new AF print(new_freq) # update `freq` in each iteration of the loop freq <- new_freq } ## [1] 0.53 ## [1] 0.51 ## [1] 0.52 "],["adding-a-population-size-variable.html", "5.12 Adding a population size variable", " 5.12 Adding a population size variable Using the freq variable also gives us more flexibility than hard-coding an allele frequency into the rbinom command. Add to your code so that we also provide Ne (effective population size) as a variable (without updating it in the for loop). # set effective population size outside of for loop Ne <- 100 # start an initial AF of 0.5 freq <- 0.5 for (i in 1:3) { # run rbinom to generate the AF for the next generation new_freq <- rbinom(n = 1, size = Ne, prob = freq) / Ne # print new AF print(new_freq) # update `freq` in each iteration of the loop freq <- new_freq } ## [1] 0.53 ## [1] 0.47 ## [1] 0.43 "],["changes-in-af-over-generations.html", "5.13 Changes in AF over generations", " 5.13 Changes in AF over generations Try increasing the number of generations we run the simulation for. What patterns of change do you observe in the allele frequencies? Ne <- 100 freq <- 0.5 for (i in 1:20) { new_freq <- rbinom(n = 1, size = Ne, prob = freq) / Ne print(new_freq) freq <- new_freq } ## [1] 0.53 ## [1] 0.44 ## [1] 0.41 ## [1] 0.48 ## [1] 0.55 ## [1] 0.49 ## [1] 0.5 ## [1] 0.5 ## [1] 0.44 ## [1] 0.48 ## [1] 0.51 ## [1] 0.46 ## [1] 0.45 ## [1] 0.48 ## [1] 0.46 ## [1] 0.51 ## [1] 0.55 ## [1] 0.58 ## [1] 0.54 ## [1] 0.56 The allele frequency starts approaching either 0 or 1. "],["storing-afs-in-a-vector.html", "5.14 Storing AFs in a vector", " 5.14 Storing AFs in a vector To plot how the AF changes over time, we can store the AF at each generation in a vector. Vectors R’s version of a list, and are formed with the c() function, which stands for “combine”: my_vec <- c(0.5, 0.6) my_vec ## [1] 0.5 0.6 You can append elements to a vector called my_vec by running: my_vec <- c(my_vec, new_element). Modify the code block with our for loop to create a vector for storing allele frequencies, and then append the updated AF to it every generation. We need to create the vector before the for loop, and then append to the vector within the for loop. Ne <- 100 freq <- 0.5 # create vector to store AFs in freq_vector <- freq for (i in 1:20) { new_freq <- rbinom(n = 1, size = Ne, prob = freq) / Ne # add new freq to the AF vector freq_vector <- c(freq_vector, new_freq) freq <- new_freq } freq_vector ## [1] 0.50 0.52 0.64 0.63 0.65 0.63 0.61 0.68 0.68 0.65 0.63 0.63 0.64 0.62 0.57 ## [16] 0.60 0.61 0.63 0.64 0.65 0.68 "],["reformatting-afs-for-plotting.html", "5.15 Reformatting AFs for plotting", " 5.15 Reformatting AFs for plotting Because ggplot requires its input data to be formatted as a table, we have to convert freq_vector into some form of table (ex: a tibble or dataframe). sim_results <- tibble(af = freq_vector) head(sim_results) ## # A tibble: 6 × 1 ## af ## <dbl> ## 1 0.5 ## 2 0.52 ## 3 0.64 ## 4 0.63 ## 5 0.65 ## 6 0.63 This table contains the information that we want on the plot’s y axis. We can now add in a column containing the plot’s x axis data, which is the generation that each AF value corresponds to. sim_results <- tibble(af = freq_vector, gen = 1:21) head(sim_results) ## # A tibble: 6 × 2 ## af gen ## <dbl> <int> ## 1 0.5 1 ## 2 0.52 2 ## 3 0.64 3 ## 4 0.63 4 ## 5 0.65 5 ## 6 0.63 6 Why does the gens column range from 1 to 21 (instead of 1 to 20)? We add our starting allele frequency to freq_vector, and then simulate for 20 generations. This means that we end up with 21 AFs in our vector. "],["plotting-af-trajectory.html", "5.16 Plotting AF trajectory", " 5.16 Plotting AF trajectory Plot the trajectory of AFs over time with ggplot. ggplot(data = sim_results, aes(x = gen, y = af)) + geom_line() "],["simulating-different-parameters-with-a-function.html", "5.17 Simulating different parameters with a function", " 5.17 Simulating different parameters with a function It would be nice to be able to run our Wright-Fisher simulation with different parameters – like different starting allele frequencies, population sizes, etc. – without having to edit the for loop code every time. We can use a function to generalize the code above so we can easily re-run it. The structure of an R function You’ve already encountered many functions in R, even if you didn’t realize it at the time - rbinom, ggplot, and print are all examples of functions. An R function has four parts: <Name> <- function(<Argument(s)>) { <Body> <return()> } Name − The function is stored in your R environment as an object with this name, and you use the name to call it Argument(s) − Optional; input values that the function performs operations on Body − The code that describes what the function does Return − Optional; a return statement allows the function to return a value to the user. Without a return statement, you won’t be able to access the function’s output Here’s an example function that takes in three parameters for running rbinom, and returns the output of rbinom. binom_sim <- function(myN, mySize, myProb) { output <- rbinom(myN, mySize, myProb) return(output) } How do I know when to use a function? Functions are useful whenever you have code that you want to run multiple times with slightly different parameters. If you find yourself copying over code several times and changing just a few things, you should consider writing a function instead. "],["creating-a-wright-fisher-function.html", "5.18 Creating a Wright-Fisher function", " 5.18 Creating a Wright-Fisher function We want our function to take in parameters for the starting allele frequency, population size, and number of generations to simulate. It should return the sim_results dataframe so that we can plot the allele frequency trajectory. To write a function, we can put the code that we just wrote into the function body: run_sim <- function(Ne, freq, generations) { # note how we don't define our initial parameters for Ne, freq, etc. # because we're passing in those parameters as arguments freq_vector <- freq for (i in 1:generations) { new_freq <- rbinom(n = 1, size = Ne, prob = freq) / Ne freq_vector <- c(freq_vector, new_freq) freq <- new_freq } # convert vector of AFs into a tibble for plotting sim_results <- tibble(afs = freq_vector, gen = 1:(generations+1)) # return the tibble of AFs, so that we can access the results return(sim_results) } "],["running-a-function.html", "5.19 Running a function", " 5.19 Running a function The code block we just wrote defines the function (i.e., tells R what it should do). Now we can run the function with parameters of our choosing and plot the output: # run function results <- run_sim(Ne = 1000, freq = 0.5, generations = 10000) # plot output ggplot(data = results, aes(x = gen, y = afs)) + geom_line() Run your run_sim function a few times with different input population sizes and AFs. How does changing these inputs affect the AF trajectories that you see? # simulate a very large population results <- run_sim(Ne = 100000, freq = 0.5, generations = 1000) # plot output ggplot(data = results, aes(x = gen, y = afs)) + geom_line() # simulate a population with AF closer to 0 results <- run_sim(Ne = 1000, freq = 0.1, generations = 1000) # plot output ggplot(data = results, aes(x = gen, y = afs)) + geom_line() In general, decreasing the population size or shifting the starting AF away from 0.5 will decrease the time to fixation for an allele. "],["conclusion-3.html", "5.20 Conclusion", " 5.20 Conclusion In this lab, we built a Wright-Fisher simulation for one allele, allowing us to track how we expect its frequency to change over time under the principles of genetic drift. Within each simulated generation, we drew the number of allele carriers in the next generation from a binomial distribution. We performed these AF draws within a for loop, allowing us to update the current AF with each new generation. Finally, we wrapped our Wright-Fisher simulation code into a function, allowing us to easily re-run our simulation with different parameters for the starting AF, population size, and number of generations to simulate for. We observed that smaller population sizes and more extreme AFs (closer to 0 or 1) generally decrease an allele’s time to fixation. This simple simulation forms the core of most models used in evolutionary genetics research, which often extend this model to simulate more complex phenomena (such as different forms of selection). "],["homework-3.html", "5.21 Homework", " 5.21 Homework One way to extend our simple Wright-Fisher model is to add in selection as a parameter. Selection affects our model by altering the probability of sampling our allele of interest each generation (e.g., positive selection increases the probability, and negative selection decreases it). Previously, we assumed that this probability was equivalent to the allele’s frequency, or \\(p = \\frac{i}{N_e}\\), where \\(N_e\\) is the population size and \\(i\\) is the number of individuals who carry the allele. For the purposes of this homework, we assume that in a model with selection, this probability is instead: \\[ p = \\frac{i(1 + s)}{N_e - i + i(1+s)} \\] where \\(s\\) is the selection coefficient, and ranges from -1 to 1. What does this probability become in the absence of selection (i.e., when \\(s = 0\\))? The probability becomes \\(\\frac{i}{N_e}\\), which is the same as the allele frequency. 5.21.0.1 Learning Objectives Practice writing functions in R Interpret allele frequency trajectories under selection and drift 5.21.0.2 Assignment In the code block below, modify your run_sim function so that it takes in a selection coefficient s as a parameter. Run the simulation a few times with and without (s = 0) selection, but keeping other parameters the same (Ne = 10000, freq = 0.5, generations = 10000). What do you notice about the allele frequency trajectories? Note that most selection coefficients are thought to be extremely small – the largest known selection coefficients in humans are around 0.05. Solution # simulation function with selection run_sim_selection <- function(Ne, freq, generations, s) { freq_vector <- freq for (i in 1:generations) { # calculate p, the probability of sampling the allele, based on s i <- freq * Ne # number of individuals who currently carry the allele p <- i*(1+s) / (Ne - i + i*(1+s)) # prob is now `p`, rather than `freq` new_freq <- rbinom(n = 1, size = Ne, prob = p) / Ne freq_vector <- c(freq_vector, new_freq) freq <- new_freq } # convert vector of AFs into a tibble for plotting sim_results <- tibble(afs = freq_vector, gen = 1:(generations+1)) # return the tibble of AFs, so that we can access the results return(sim_results) } Run and plot the simulation with selection: results <- run_sim_selection(Ne = 10000, freq = 0.5, generations = 10000, s = -0.001) ggplot() + geom_line(data = results, aes(x = gen, y = afs)) + ylim(0, 1) + ylab("Allele frequency") + xlab("Generation") + ggtitle("Simulation with selection") + theme(plot.title = element_text(hjust = 0.5)) # to center the title Run and plot the simulation without selection: results <- run_sim_selection(Ne = 10000, freq = 0.5, generations = 10000, s = 0) ggplot() + geom_line(data = results, aes(x = gen, y = afs)) + ylim(0, 1) + ylab("Allele frequency") + xlab("Generation") + ggtitle("Simulation without selection") + theme(plot.title = element_text(hjust = 0.5)) # to center the title We observe that selection tends to decrease the time it takes for an allele to either fix or go extinct, because it directionally biases the probability of sampling that allele. Decreasing the absolute value of the selection coefficient will make the simulation behave more like drift. "],["population-structure.html", "6 Population structure", " 6 Population structure In this lab, we’ll perform principal component analysis (PCA) to visualize how genetic variation segregates between populations. 6.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Describe the data stored in a Variant Call Format (VCF) file. Plot and interpret an allele frequency spectrum. Perform and visualize the results of a principal component analysis. "],["what-is-a-population.html", "6.1 What is a population?", " 6.1 What is a population? In population genetics, the term population refers to a group of interbreeding individuals. Determining whether a group of individuals is a “population” is subjective. Groups exchange migrants at different rates (a process called gene flow), and there is no definitive boundary for when they constitute separate populations. "],["population-structure-1.html", "6.2 Population structure", " 6.2 Population structure Population structure is a consequence of the fact that when two groups of individuals do not freely interbreed, the two populations typically develop different patterns of genetic variation. Individuals within a population tend to be share greater genetic similarity with each other than with individuals in other populations. These differences manifest through differences in allele frequencies among populations, and result from genetic drift, natural selection, and other evolutionary forces. We can measure such allele frequency differences to reveal evolutionary relationships among populations, as well as evidence of historical natural selection. Fig. 1. Two populations polymorphic for alleles A and a. The frequency of A in Population 1 is \\(0.83\\), while its frequency in Population 2 is \\(0.15\\). "],["geography-of-genetic-variants.html", "6.3 Geography of Genetic Variants", " 6.3 Geography of Genetic Variants One quick way to visualize population structure in humans is to look at the allele frequencies of genetic variants in different regions of the world. The Geography of Genetic Variants (GGV) browser is a website that plots allele frequencies from the 1000 Genomes dataset. For a given variant, GGV plots piecharts of its frequency in the 26 populations in 1000 Genomes, superimposed over the population’s geographical location. While some variants have very similar frequencies across populations, others are much more common in specific populations – usually suggesting that these populations are more closely related to each other. Fig. 2. GGV visualization of the allele frequencies for a SNP at chr1:222087833. "],["setup-3.html", "6.4 Setup", " 6.4 Setup We’ll use the 1000 Genomes data to visualize genetic differentiation between its populations. 6.4.1 R packages library(tidyverse) "],["genotype-data.html", "6.5 Genotype data", " 6.5 Genotype data We’ve summarized genotype data from the 1000 Genomes Project into two files: all_variants.txt.gz, which contains a random selection of variants on chr21 common_variants.txt, which contains only those variants in all_variants that are common across populations # all variants all <- read.table("all_variants.txt.gz") # only common variants common <- read.table("common_variants.txt.gz") # preview first 10 columns of `all` dataframe head(all[, 1:10]) ## AF AFR_AF AMR_AF EAS_AF EUR_AF SAS_AF HG00096 HG00097 HG00099 ## chr21_10005999 0.02 0.06 0.00 0 0.00 0.00 0 0 0 ## chr21_10325486 0.02 0.00 0.01 0 0.03 0.04 0 0 0 ## chr21_10336823 0.00 0.00 0.00 0 0.00 0.00 0 0 0 ## chr21_10337236 0.00 0.00 0.00 0 0.00 0.00 0 0 0 ## chr21_10339129 0.00 0.00 0.00 0 0.00 0.00 0 0 0 ## chr21_10339141 0.00 0.00 0.00 0 0.00 0.00 0 0 0 ## HG00100 ## chr21_10005999 0 ## chr21_10325486 0 ## chr21_10336823 0 ## chr21_10337236 0 ## chr21_10339129 0 ## chr21_10339141 0 The index of the dataframe is the variant ID. * The first column (AF) contains the variant’s allele frequency (AF) dataset-wide. * The next five columns contain the variant’s AF in each of the five 1000 Genomes superpopulations. * The rest of the columns provide variant genotypes for each individual in 1000 Genomes, where: * 0 is homozygous reference * 1 is heterozygous * 2 is homozygous for variant "],["metadata.html", "6.6 Metadata", " 6.6 Metadata We’ll also read in a metadata file, which tells us which population each individual is from. metadata <- read.table("integrated_call_samples.txt", header = TRUE) head(metadata) ## sample pop superpop sex ## 1 HG00096 GBR EUR male ## 2 HG00097 GBR EUR female ## 3 HG00099 GBR EUR female ## 4 HG00100 GBR EUR female ## 5 HG00101 GBR EUR male ## 6 HG00102 GBR EUR female "],["the-allele-frequency-spectrum.html", "6.7 The allele frequency spectrum", " 6.7 The allele frequency spectrum One common visualization of genotype data is the allele frequency spectrum (AFS), which is the distribution of the allele frequencies of the variants. Plot the AFS of all variants, using the data in the AF column. ggplot(data = all, aes(x = AF)) + geom_histogram(bins = 100) Interpreting the AFS The allele frequencies in this dataset range from 0 to 1, with an exponential decay from zero, indicating that the majority of variants are rare. This is the expected shape of an AFS, since all variants arise in one individual and are unlikely to spread widely through the population just by chance. This distribution is exacerbated in human populations, where recent population expansions have resulted in an excess of rare variation. "],["theoretical-afs.html", "6.8 Theoretical AFS", " 6.8 Theoretical AFS Population geneticists have estimated that under neutral demographic expectations, each bin of the AFS should have a height that is equal to 1 over its bin number. We can use this to plot the expected AFS: # make dataframe with theoretical AFS bins # create `af_bin` column with the bin number ideal_pop <- tibble(af_bin = 1:100) %>% # create `prop` column with the expected proportion of variants mutate(., prop = 1 / af_bin) head(ideal_pop) ## # A tibble: 6 × 2 ## af_bin prop ## <int> <dbl> ## 1 1 1 ## 2 2 0.5 ## 3 3 0.333 ## 4 4 0.25 ## 5 5 0.2 ## 6 6 0.167 # plot expected AFS ggplot(ideal_pop, aes(x = af_bin, y = prop)) + geom_bar(stat = "identity") How does this compare to the AFS we see from human data? The human AFS has many more rare variants, which manifests as a higher peak on the left side of the AFS. This is due to recent population expansion in humans, which results in more human individuals and an accumulation of excess new rare variation. How would you expect the AFS to look for a contracting population (ex: endangered species)? A contracting population would result in the extinction of many alleles, resulting in more variants that drift to high frequency or go extinct. The AFS for this type of population would look more flat than the neutral expectation (fewer rare alleles, more common ones). "],["af-correlations-between-populations.html", "6.9 AF correlations between populations", " 6.9 AF correlations between populations What if we compare AFs between populations? Do we expect the same variant to have the same AFs in, for example, Africa and Europe? Plot African vs. European AF on a scatterplot. ggplot(all, aes(x = AFR_AF, y = EUR_AF)) + geom_point() Most of the variants lie near the x = y line, showing that there’s a lot of correlated AFs between African and European populations. This is due to these populations’ recent common ancestry. Outlier variants, with very different frequencies in different populations, may have reached these different AFs due to the effects of selection – which we’ll discuss in a later module. Plot AF correlations for some other population pairs. Do you notice any differences in the distributions? # east asian vs. european ggplot(all, aes(x = EAS_AF, y = EUR_AF)) + geom_point() # east asian vs. south asian ggplot(all, aes(x = EAS_AF, y = SAS_AF)) + geom_point() There’s less spread away from the y = x line for the EAS-SAS comparison. Because these populations share a common ancestor more recently than EAS-AFR, there has been less time for drift to change AFs between the populations. "],["common-variation.html", "6.10 Common variation", " 6.10 Common variation For the rest of this lab, we’ll use the common dataframe, which includes only variants where \\(0.05 < \\textrm{AF} < 0.95\\). We can look at where this set of common variants lies on the full AFS by adding vertical lines at the cutoff allele frequencies: ggplot(data = all, aes(x = AF)) + geom_histogram(bins = 100) + geom_vline(xintercept = 0.05, linetype = "dashed", color = "blue") + geom_vline(xintercept = 0.95, linetype = "dashed", color = "brown") Plot the AFS of the common dataframe, including the dashed lines we used above. ggplot(data = common, aes(x = AF)) + geom_histogram() + geom_vline(xintercept = 0.05, linetype = "dashed", color = "blue") + geom_vline(xintercept = 0.95, linetype = "dashed", color = "brown") ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. All of these variants lie within the dashed lines. Even with just common variation, we still observe an exponential decay of the allele frequencies. Also note that there are only 960 variants in the common dataframe – substantially less than the 10,000 in the all dataframe. Why only work with common variants? Rare variants are more likely to show fine-grained population structure – for example, a variant may be carried by just one individual, or just one family. Because there are so many rare variants, including them causes differences between individuals to be more pronounced than differences between populations. While this is a biologically true statement, it makes it harder to visualize population structure, which is why we subset to common variation for PCA. "],["principal-component-analysis.html", "6.11 Principal component analysis", " 6.11 Principal component analysis Principal component analysis (PCA) is a method for representing high-dimensional data (i.e., data with many variables) within a smaller number of dimensions. In our case, every individual in the VCF has genotype measurements for hundreds of variants. You can think of PCA as a projection all the individuals in our dataset into a cloud, where their position is determined by their combination of genotypes. The first principal component (PC) is the vector through the cloud of data points that captures the greatest possible variance. The second PC is the vector that captures the second greatest possible variance, and must also be perpendicular to the first vector. The same idea applies to the third, fourth, fifth, etc. PCs. Fig. 3. A PCA plot that simplifies three-dimensional data into two dimensions. For an in-depth visual walkthrough of PCA, you can go to this website. "],["reformatting-data-for-pca.html", "6.12 Reformatting data for PCA", " 6.12 Reformatting data for PCA We’re using R’s prcomp function to perform PCA on our genotype data. This function takes a matrix where the rows are the data objects (i.e., individuals) and the columns are the associated measurements (i.e., variants). First, run the code below to subset our data to just the genotypes: # subset to just genotype columns gt_matrix <- common[, 7:2510] %>% as.matrix() # view first 10 columns of matrix head(gt_matrix[, 1:10]) ## HG00096 HG00097 HG00099 HG00100 HG00101 HG00102 HG00103 HG00104 ## chr21_10467583 0 0 1 0 0 1 0 0 ## chr21_10605468 1 0 0 0 1 0 0 0 ## chr21_10616824 1 0 0 0 1 0 0 0 ## chr21_10666513 0 0 0 0 0 0 0 0 ## chr21_10700275 0 0 0 0 0 0 0 0 ## chr21_10728655 1 0 0 0 0 0 0 0 ## HG00105 HG00106 ## chr21_10467583 1 0 ## chr21_10605468 0 0 ## chr21_10616824 0 0 ## chr21_10666513 0 0 ## chr21_10700275 1 0 ## chr21_10728655 0 0 We then transpose the matrix with prcomp’s t function so that the rows are individuals and the columns are variants: # transpose (i.e., rotate) gt_matrix_T <- t(gt_matrix) # view first 10 columns of transposed matrix head(gt_matrix_T[, 1:10]) ## chr21_10467583 chr21_10605468 chr21_10616824 chr21_10666513 ## HG00096 0 1 1 0 ## HG00097 0 0 0 0 ## HG00099 1 0 0 0 ## HG00100 0 0 0 0 ## HG00101 0 1 1 0 ## HG00102 1 0 0 0 ## chr21_10700275 chr21_10728655 chr21_10732526 chr21_12976114 ## HG00096 0 1 0 0 ## HG00097 0 0 0 0 ## HG00099 0 0 0 0 ## HG00100 0 0 0 0 ## HG00101 0 0 1 0 ## HG00102 0 0 0 0 ## chr21_12977074 chr21_13065545 ## HG00096 0 0 ## HG00097 0 0 ## HG00099 0 0 ## HG00100 0 0 ## HG00101 0 0 ## HG00102 0 0 "],["performing-pca.html", "6.13 Performing PCA", " 6.13 Performing PCA We perform PCA on our genotype matrix with prcomp. pca <- prcomp(gt_matrix_T) Our output is a prcomp object. This object comprises several tables, which you can preview by typing pca$ into the console and seeing what R suggests: sdev: standard deviations of the principle components rotation, center, scale: tables we won’t use in this lab x: coordinates of the data objects (the 1000 Genomes individuals) on each PC "],["reformatting-pca-output.html", "6.14 Reformatting PCA output", " 6.14 Reformatting PCA output We can plot our PCA output using the information in pca$x. # extract `x` table x <- pca$x # preview first 10 columns head(x[, 1:10]) Every row of x is an individual, every column is a PC (going up to 960 PCs!), and the value in each cell represents the sample’s coordinate on each PC axis. Run the code below to create a dataframe of the first three PCs to plot: # create column of sample names pca_results <- data.frame(sample = rownames(x), PC1 = x[, 1], # PC1 values PC2 = x[, 2], # PC2 values PC3 = x[, 3]) # PC3 values head(pca_results) ## sample PC1 PC2 PC3 ## HG00096 HG00096 3.060014 -5.822356 -1.2683268 ## HG00097 HG00097 2.839200 -6.278675 0.8609691 ## HG00099 HG00099 1.803619 -5.171999 0.4033319 ## HG00100 HG00100 3.160473 -4.504760 1.8926507 ## HG00101 HG00101 4.035908 -4.545304 0.9407191 ## HG00102 HG00102 3.608347 -4.668695 0.7327117 "],["annotate-with-population-labels.html", "6.15 Annotate with population labels", " 6.15 Annotate with population labels Our last step is adding a column to our PCA dataframe with information about each individual’s population. To do this, we merge pca_results with our metadata table. The merge function combines two tables, merging them by matching a column of your choice (specified with by =). # merge pca_results and metadata pca_results <- merge(pca_results, metadata, # specify columns to merge on by.x = "sample", by.y = "sample") head(pca_results) ## sample PC1 PC2 PC3 pop superpop sex ## 1 HG00096 3.060014 -5.822356 -1.2683268 GBR EUR male ## 2 HG00097 2.839200 -6.278675 0.8609691 GBR EUR female ## 3 HG00099 1.803619 -5.171999 0.4033319 GBR EUR female ## 4 HG00100 3.160473 -4.504760 1.8926507 GBR EUR female ## 5 HG00101 4.035908 -4.545304 0.9407191 GBR EUR male ## 6 HG00102 3.608347 -4.668695 0.7327117 GBR EUR female "],["pca-plot.html", "6.16 PCA plot", " 6.16 PCA plot Create a scatterplot of PC1 vs. PC2, coloring by the superpop column. ggplot(data = pca_results, aes(x = PC1, y = PC2, color = superpop)) + geom_point() PC1 separates out the African populations from other populations. This is in line with our knowledge that all non-African populations descend from historical migrations out of Africa – African populations contain significant genetic diversity that is not represented outside of Africa. PC2 seems to separate the East Asian and European populations from the other three superpopulations. Repeat the plot with PC2 vs. PC3. Which superpopulations do you observe separating on PC3? ggplot(data = pca_results, aes(x = PC2, y = PC3, color = superpop)) + geom_point() PC3 separates out the Admixed American and South Asian populations, which were collapsed into one group in the first PCA plot. "],["proportion-of-variance-explained.html", "6.17 Proportion of variance explained", " 6.17 Proportion of variance explained It’s hard to tell from the PCA plot whether the separation of populations we see is meaningful, or if the plot is just exaggerating extremely minor differences between groups. We quantify this by calculating the proportion of variance explained for each PC. This tells us how much of the variation in our data is being captured by PC1, PC2, etc. Variance is the square of the standard deviation, so we can calculate proportion of variance explained from the sdev item in our pca object. Each value corresponds to the standard deviation for one PC. sd <- pca$sdev head(sd) ## [1] 5.692102 3.818282 2.122236 1.954976 1.476041 1.450018 The proportion of variance explained by a PC is its variance, divided by the sum of the variances across all PCs. Conveniently, you can calculate this for every PC at once in R: # divide variance of each PC by sum of all variances var_explained <- sd^2 / sum(sd^2) # proportion of variance explained for: var_explained[1] # PC1 ## [1] 0.09645901 var_explained[2] # PC2 ## [1] 0.04340437 var_explained[3] # PC3 ## [1] 0.01340864 So, PC1 explains only 9.65% of the variance in our data, PC2 explains 4.34%, and PC3 explains 1.34%. Add x and y axis labels to your plots with the proportion of variance explained by each PC. This is common practice for PCA. ggplot(data = pca_results, aes(x = PC1, y = PC2, color = superpop)) + geom_point() + xlab("PC1 (9.65%)") + ylab("PC2 (4.34%)") ggplot(data = pca_results, aes(x = PC2, y = PC3, color = superpop)) + geom_point() + xlab("PC2 (4.34%)") + ylab("PC3 (1.34%)") "],["conclusion-4.html", "6.18 Conclusion", " 6.18 Conclusion In this lab, we used genotype data from the 1000 Genomes Project to calculate two measures of population structure. We explored the Geography of Genetic Variants browser, a useful resource for visualizing allele frequency differences between human populations. Using genotype data from the 1000 Genomes Project, we plotted the allele frequency spectrum of variants in human populations. We saw that humans carry an excess of rare variation due to recent population expansion. Finally, we used principal component analysis to cluster individuals in our dataset by their genotype information. Plotting individuals in PCA space allowed us to distinguish the five superpopulations of 1000 Genomes. "],["homework-4.html", "6.19 Homework", " 6.19 Homework We’ll now perform PCA using all SNPs in the initial VCF – not just those that were common in 1000 Genomes individuals. In the optional homework, you’ll also use your newly generated PCA plot to predict the ancestry of an unknown sample. 6.19.0.1 Learning Objectives Perform and interpret the results of a PCA Become familiar with understanding and reusing code "],["required-homework-1.html", "6.20 Required homework", " 6.20 Required homework Assignment: Re-run the steps we used to generate our PCA plot, this time using the all dataframe. Do these plots look any different from our plots with just common variants? Solution # extract genotypes and convert to matrix gt_matrix_all <- all[, 7:2510] %>% as.matrix() # transpose gt_matrix_T_all <- t(gt_matrix_all) # perform PCA pca_all <- prcomp(gt_matrix_T_all) # extract coordinates from PCA object x_all <- pca_all$x # create dataframe for plotting pca_results_all <- data.frame(sample = rownames(x_all), PC1 = x_all[, 1], PC2 = x_all[, 2], PC3 = x_all[, 3]) # merge with metadata pca_results_all <- merge(pca_results_all, metadata, # specify columns to merge on by.x = "sample", by.y = "sample") # calculate variance explained by each PC var_explained_all <- pca_all$sdev^2 / sum(pca_all$sdev^2) # print for PC1-PC3 var_explained_all[1:3] ## [1] 0.09154081 0.03824824 0.01207284 # PC1 vs. PC2 plot ggplot(data = pca_results_all, aes(x = PC1, y = PC2, color = superpop)) + geom_point() + xlab("PC1 (9.15%)") + ylab("PC2 (3.82%)") # PC2 vs. PC3 plot ggplot(data = pca_results_all, aes(x = PC2, y = PC3, color = superpop)) + geom_point() + xlab("PC2 (3.82%)") + ylab("PC3 (1.21%)") The PCA plots actually look pretty similar to the plots with just common variants! "],["optional-homework-1.html", "6.21 Optional homework", " 6.21 Optional homework We can think of our PCA as a model of human individuals. If we have a mystery individual but we know their genotypes for the variants in our PCA, we can predict where they should lie in PCA space and thus guess their ancestry. We’ve prepared a file, unknown.txt, which contains genotypes for one mystery sample (NA21121). We’ll compare it to the PCA model that you created for the required homework. Follow the instructions to predict NA21121’s placement on your PCA plot. 6.21.0.1 Prepare unknown sample for PCA Assignment: Read in unknown.txt, convert it to a matrix, and transpose. Solution # read VCF unknown <- read.table("unknown.txt") %>% as.matrix() # transpose matrix unknown_T <- t(unknown) 6.21.0.2 Predict PCA placement of unknown sample Assignment: Run the code block below to predict and plot NA21121 on top of your PCA plot from the required homework. If necessary, plot PC2 vs. PC3 as well. What superpopulation do you think NA21121 is from? Solution # predict pca placement of unknown data unknown_pca <- predict(pca_all, unknown_T) # create dataframe from predicted PCA unknown_results <- data.frame("PC1" = unknown_pca[, "PC1"], "PC2" = unknown_pca[, "PC2"], "PC3" = unknown_pca[, "PC3"], "sample" = "NA21121") # plot PC1 vs. PC2 and then predicted sample ggplot() + # PCA plot from required homework geom_point(data = pca_results_all, aes(x = PC1, y = PC2, color = superpop)) + # plots the unknown sample's location on the PCs geom_label(data = unknown_results, aes(x = PC1, y = PC2, label = sample)) + xlab("PC1 (9.15%)") + ylab("PC2 (3.82%)") # plot PC2 vs. PC3 ggplot() + geom_point(data = pca_results_all, aes(x = PC2, y = PC3, color = superpop)) + geom_label(data = unknown_results, aes(x = PC2, y = PC3, label = sample)) + xlab("PC2 (3.82%)") + ylab("PC3 (1.21%)") NA21121 seems to be part of the SAS (South Asian) superpopulation. If we look up the sample ID in the 1000 Genomes database, we can confirm that it’s part of the Gujarati Indians in Houston, TX. "],["genome-wide-association-studies-i.html", "7 Genome-wide association studies I", " 7 Genome-wide association studies I In this lab, we’ll introduce and discuss the limitations of genome-wide association studies (GWAS). 7.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Explain the statistical method that underlies GWAS. Describe the statistical challenges of GWAS. Understand how linkage disequilibrium helps and hinders GWAS. Interpret common GWAS plots and summary statistics. "],["association-studies.html", "7.1 Association studies", " 7.1 Association studies One of the central goals of human genetics is understanding the relationship between genotype and phenotype. Genome-wide association studies (GWAS) emerged ~20 years ago as a useful approach for discovering genetic variation that underlies variation in human traits. To conduct GWAS, you: Go through every variant in the genome Ask if its allele frequency differs between individuals who have or don’t have a phenotype of interest For most variants (Fig. 1, SNP 1), there will be very little difference Identify the variants with the largest association between genotype and phenotype (Fig. 1, SNP 2) Fig. 1. In this GWAS cohort, SNP 2 is significantly associated with the phenotype. The phenotype can be any measurable trait, whether it’s binary (ex: if someone has a disease) or continuous (ex: height). "],["gwas-is-just-linear-regression.html", "7.2 GWAS is just linear regression", " 7.2 GWAS is just linear regression At their core, GWAS involve fitting linear models to test for relationships between variants and phenotypes using data from large samples of individuals. As with the linear models we covered in the DNM module, GWAS fits a line to a set of points. In this case, each point is one individual in the dataset, stratified by their genotype for a variant of interest. Fig. 2 (source). GWAS fits a linear model for every variant, where the x axis is genotype and the y axis is a phenotype. Because there are so many variants in the genome and we perform a separate statistical test for each one, we often end up fitting millions of linear models for a GWAS. "],["multiple-testing.html", "7.3 Multiple testing", " 7.3 Multiple testing What are statistical challenges of performing a test multiple times? When we perform any test multiple times, we increase the risk that a “significant” result is only significant by chance. Under the null hypothesis, we assume that p-values follow a uniform distribution (i.e., a flat distribution from 0 to 1). We can plot this null distribution in R: # generate 1,000,000 "p-values" from a uniform distribution pvalues <- runif(1000000) # histogram with R's base plotting function hist(pvalues) If we use the typical p-value threshold of \\(0.05\\), 5% of our tests will have \\(p < 0.05\\), even though these p-values were simulated from a null distribution (i.e., no real association). How do we correct for multiple testing? One common multiple testing correction method, Bonferroni correction, sets a stricter p-value threshold. With Bonferroni, you divide your desired p-value by the number of independent tests you conducted. Are GWAS tests (variants) statistically independent? How does this affect our p-value threshold? As we learned in the LD module, the genotypes of nearby variants are correlated. This non-independence means that we can be less strict with multiple testing correction, because we aren’t performing as many independent tests as we think we are. Researchers have calculated that \\(\\mathbf{5*10^{-8}}\\) is an appropriate p-value threshold for GWAS in humans, given the amount of LD in human genomes. "],["ld-and-gwas.html", "7.4 LD and GWAS", " 7.4 LD and GWAS LD is both a blessing and a curse for GWAS. On one hand, LD means that we need not genotype every SNP to discover associations. We merely need to genotype “tag SNPs”, which are in LD with variants that causally influence the phenotype. On the other hand, this also means that even when we find a signficant association, it is often challenging to disentangle the causal gene and/or variant that drives the association from all the other variants on the same haplotype. Fig. 3 (source). Even without finding the causal variant, we can still discover the causal haplotype through genotyping variants in LD . "],["imputation.html", "7.5 Imputation", " 7.5 Imputation LD also means that we can perform imputation to improve our GWAS discovery power. If we know which variants tend to occur together on the same haplotype, we can infer the presence of variants in an individual even if those SNPs were never sequenced. In imputation, you: Genotype individuals using the sequencing data you have (Fig. 4A) Use a reference panel of haplotypes to fill in variants you didn’t genotype (Fig. 4B) Perform GWAS Imputation can discover GWAS signals that were hidden in the original variant set (Fig. 4B vs. Fig. 4F), or further support signals you already found. Fig. 4 (source). Imputing variants that were not actually sequenced. "],["qq-plots.html", "7.6 QQ plots", " 7.6 QQ plots One common visualization for GWAS results is a QQ plot, which compares the distribution of p-values in our results to a null distribution (i.e., the uniform distribution that we plotted earlier). How do you make a QQ plot? Generate simulated p-values from a uniform distribution – the number of simulated p-values should equal the number of actual p-values Sort both your real and simulated p-values in descending order Plot the first, second, third, etc. p-values, where x-axis is the simulated value y-axis is the actual value Fig. 5 (source). QQ plots visualize the distriution of p-values compared to a null distribution. There are three areas of this plot where points can fall: On the \\(\\mathbf{x = y}\\) line: No association signal Above the \\(\\mathbf{x = y}\\) line: Some association signal Below the \\(\\mathbf{x = y}\\) line: Issue with our statistical test (ex: not appropriately adjusting for covariates) "],["manhattan-plots.html", "7.7 Manhattan plots", " 7.7 Manhattan plots Manhattan plots show the distribution of GWAS hits across the genome, where the y-axis is p-value. </br. Fig. 6. Manhattan plot of GWAS results. The red line is the \\(5*10^{-8}\\) genome-wide significance threshold. Why are there peaks in the Manhattan plot? Each peak is composed of variants from the same haplotype, which all have a strong association with the phenotype because of LD. "],["sample-size.html", "7.8 Sample size", " 7.8 Sample size As GWAS sample size has increased over the years, each larger study is able to discover more variants. Fig. 7 (source). Increase in GWAS discovery power with sample size. Why do we find more associations with larger studies? A larger dataset captures more rare variation A larger dataset provides more statistical power – we can more confidently say whether allele frequencies are different between individuals with and without a phenotype "],["interpreting-gwas-results.html", "7.9 Interpreting GWAS results", " 7.9 Interpreting GWAS results Let’s look at a browser of GWAS results, generated by a study that used genotype and phenotype data from the UK Biobank. UK Biobank UK Biobank is one of the largest cohorts of genotype and phenotype data available. This study has data from ~500,000 individuals across the UK, including health records and responses to surveys, all of which are publicly available for research. As an example, let’s look up associations with standing height. Fig. 8. GWAS results for standing height. For each phenotype, the browser shows a Manhattan plot of associated variants The top p-values for this trait look extremely significant Bottom of the page also has a QQ plot Although these p-values are huge, keep in mind that for the vast majority of extremely strong associations, the total proportion of variance explained is very small (< 10%). (i.e., most of the natural variation in the phenotype is not explained by that variant.) "],["conclusion-5.html", "7.10 Conclusion", " 7.10 Conclusion In this lab, we gave a conceptual overview of genome-wide association studies. GWAS are an attempt to answer one of the oldest questions in genetics: How does genotype impact phenotype? In GWAS, you go through every variant in the genome and fit a linear model to ask if genotype at that variant is associated with a phenotype of interest. Multiple testing correction accounts for the statistical burden of these tests. Linkage disequilibrium helps us discover more GWAS hits, but also limits our ability to identify causal variants/genes. QQ plots and Manhattan plots are common visualizations of GWAS results. "],["homework-5.html", "7.11 Homework", " 7.11 Homework 7.11.0.1 Learning Objectives Interpret the summary statistics typically reported in GWAS studies Understand the limitations and biases of GWAS 7.11.0.2 Assignment Find any GWAS paper. Read it and report: Phenotype being studied Sample size Population being studied (homogeneous? Multi-ethnic? If it’s multi-ethnic, how do they correct for the effect of ancestry?) For the top asssociation: p-value (would you call it significant genome wide?) Effect size Did the authors replicate the result in an independent cohort? Haplotype structure, nearby genes, causal variant Example solution Example GWAS: Genome-wide analysis identifies genetic effects on reproductive success and ongoing natural selection at the FADS locus. Phenotype: Number of children ever born Sample size:: 785,604 Population: European; no population structure correction (but did control for family structure) Top asssociation: rs201815280, chr3:85546181, A->ACACC (from Supp. Table 7) p-value: 5.25e-26, seems genome-wide significant Effect size: 0.0249 (with every copy of the ACACC allele, individuals have one more child born) Replication: Did not replicate in a cohort of 34,367 women from the FinnGen study (p = 0.177) Haplotype structure, nearby genes, causal variant: In an intron of CADM2; no causal variant or LD analysis "],["genome-wide-association-studies-ii.html", "8 Genome-wide association studies II", " 8 Genome-wide association studies II In this lab, we’ll perform a GWAS. The data and exercises for this module were adapted from a GWAS workshop created by Heather Wheeler from Loyola University Chicago. 8.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Perform GWAS of a single SNP using linear regression. Use PLINK to perform GWAS on all SNPs in a VCF. Create and interpret common GWAS visualization plots. "],["setup-4.html", "8.1 Setup", " 8.1 Setup The premise for this exercise is that you’re part of a company developing a cancer drug called . Today, we’ll perform a GWAS on resistance to two drugs (GS451 and CB1908) in 1000 Genomes lymphblastoid cell lines. The phenotype we’re interested in is \\(\\mathbf{IC_{50}}\\), defined as the concentration of the drug at which the cells experience 50% viability. 8.1.1 R packages In addition to tidyverse, we’ll use vcfR to read in genotype data and qqman to create Manhattan and QQ plots. library(tidyverse) library(vcfR) library(qqman) "],["data-2.html", "8.2 Data", " 8.2 Data GWAS requires information on both genotype and phenotype in the same individuals. The genotype data we’re using are real data from the Yoruba population in the 1000 Genomes Project, but the phenotype data is simulated. Why can’t we use real phenotype data? The combination of genotype and phenotype data poses a privacy risk, so real genotype and phenotype data are often stored in controlled-access databases such as dbGaP. Although these data are still available to researchers who want to work with it, access usually requires submitting an application to explain what your intend to do with it. "],["variant-call-format-vcf.html", "8.3 Variant Call Format (VCF)", " 8.3 Variant Call Format (VCF) Our genotype data is stored in a Variant Call Format (VCF) file. VCF files contain genotype data for variants of interest in a genome. Click on genotypes_subset.vcf in the Posit Files pane to view it. This file is a subset of a much larger VCF that we’ll use later to run a genome-wide GWAS. "],["vcf-header.html", "8.4 VCF header", " 8.4 VCF header The first section of a VCF is a multi-line header – marked by the ## character – which contains metadata and descriptions of some of the columns (like INFO and FORMAT). ##fileformat=VCFv4.2 ##fileDate=20200327 ##source=PLINKv1.90 ##contig=<ID=1,length=247169191> ##contig=<ID=2,length=242739671> ##contig=<ID=3,length=199318156> ##contig=<ID=4,length=191166588> ##contig=<ID=5,length=180617248> ##contig=<ID=6,length=170727838> ##contig=<ID=7,length=158798775> ##contig=<ID=8,length=146266471> ##contig=<ID=9,length=140174583> ##contig=<ID=10,length=135279752> ##contig=<ID=11,length=134426071> ##contig=<ID=12,length=132256834> ##contig=<ID=13,length=114114508> ##contig=<ID=14,length=106354055> ##contig=<ID=15,length=100209453> ##contig=<ID=16,length=88670345> ##contig=<ID=17,length=78634628> ##contig=<ID=18,length=76098044> ##contig=<ID=19,length=63771070> ##contig=<ID=20,length=62382908> ##contig=<ID=21,length=46924584> ##contig=<ID=22,length=49503800> ##INFO=<ID=PR,Number=0,Type=Flag,Description="Provisional reference allele, may not be based on real reference genome"> ##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype"> The final line of the header (marked with just one #) gives the names of the data columns. Note that there are over a hundred columns because each individual (1001, 1002, etc.) has their own column. #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 "],["vcf-data.html", "8.5 VCF data", " 8.5 VCF data The data section of a VCF describes genetic variants. The first 9 columns give information about the variant itself – its position, the reference/alternative alleles, etc. The rest of the columns are sample-specific, and contain the individual’s genotype at that variant. 1 558185 rs9699599 A G . . PR GT 0/0 0/0 0/0 0/1 0/0 0/1 ./. 0/0 0/0 0/0 0/1 0/0 0/0 0/0 0/0 0/1 0/0 0/1 0/0 0/0 0/0 0/0 0/0 0/0 0/0 ./. 0/0 0/0 0/0 0/0 0/1 0/0 0/1 0/1 0/0 0/1 ./. 0/1 0/1 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/1 0/0 0/1 0/0 0/0 0/0 0/1 0/0 0/1 0/0 0/0 0/0 ./. 0/0 0/0 0/0 0/1 0/0 0/1 0/0 0/1 0/0 0/1 0/0 0/0 0/1 0/0 ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. How do you interpret VCF genotypes? 0/0: homozygous reference (does not carry the variant) 0/1 or 1|0: heterozygous 1/1: homozygous alternate (both chromosomes have the variant) ./.: Missing genotype (could not be confidently called) The sample-specific columns often include additional genotype information, like the number of sequencing reads from the individual that support the reference vs. alternative alleles. The included fields are specified column 9 (FORMAT) (which in this case just reads GT, for “genotype”). "],["reading-in-genotype-data.html", "8.6 Reading in genotype data", " 8.6 Reading in genotype data Because VCF format can be hard to work with, we’ll use the vcfR package to manipulate our genotype data. # load the VCF with vcfR vcf <- read.vcfR("genotypes_subset.vcf") ## Scanning file to determine attributes. ## File attributes: ## meta lines: 27 ## header_line: 28 ## variant count: 72 ## column count: 185 ## Meta line 27 read in. ## All meta lines processed. ## gt matrix initialized. ## Character matrix gt created. ## Character matrix gt rows: 72 ## Character matrix gt cols: 185 ## skip: 0 ## nrows: 72 ## row_num: 0 ## Processed variant: 72 ## All variants processed "],["tidying-vcf.html", "8.7 Tidying VCF", " 8.7 Tidying VCF We’ll first work with just the first SNP in the dataset, using the vcfR2tidy function to isolate the SNP of interest and extract its genotypes. # extract first SNP, convert to tidy df, and get genotypes test_snp_gt <- vcfR2tidy(vcf[1, ])$gt ## Extracting gt element GT head(test_snp_gt) ## # A tibble: 6 × 5 ## ChromKey POS Indiv gt_GT gt_GT_alleles ## <int> <int> <chr> <chr> <chr> ## 1 1 558185 1001 0/0 A/A ## 2 1 558185 1002 0/0 A/A ## 3 1 558185 1003 0/0 A/A ## 4 1 558185 1004 0/1 A/G ## 5 1 558185 1005 0/0 A/A ## 6 1 558185 1006 0/1 A/G Every row in the test_snp_gt dataframe is a different individual in the VCF. "],["counting-allele-dosage.html", "8.8 Counting allele dosage", " 8.8 Counting allele dosage We’re often interested in encoding genotypes as a 0, 1, or 2, which you can think of as the dosage of the minor allele. This is an additive model, and assumes that the phenotype of the heterozygote is intermediate between those of the two homozygotes. We can use the table function on the gt_GT_alleles column to quickly check how many individuals have each genotype. # tabulate genotype counts table(test_snp_gt$gt_GT_alleles) ## ## A/A A/G ## 66 20 Now we’ll use the mutate function to create a new column of the dataframe that counts the dosage of the minor allele (i.e., how many G’s each person has at that SNP): # convert genotypes to counts (i.e., dosage) of minor allele test_snp_gt <- test_snp_gt %>% # count number of Gs mutate(dosage = str_count(gt_GT_alleles, "G")) %>% drop_na() head(test_snp_gt) ## # A tibble: 6 × 6 ## ChromKey POS Indiv gt_GT gt_GT_alleles dosage ## <int> <int> <chr> <chr> <chr> <int> ## 1 1 558185 1001 0/0 A/A 0 ## 2 1 558185 1002 0/0 A/A 0 ## 3 1 558185 1003 0/0 A/A 0 ## 4 1 558185 1004 0/1 A/G 1 ## 5 1 558185 1005 0/0 A/A 0 ## 6 1 558185 1006 0/1 A/G 1 Checking our work with table If we run table on the dosage column, we should get the same breakdown of genotypes as we got from the gt_GT_alleles columns. # make sure we get the same genotype counts table(test_snp_gt$dosage) ## ## 0 1 ## 66 20 "],["phenotype-data.html", "8.9 Phenotype data", " 8.9 Phenotype data Our phenotype for this GWAS is the \\(\\mathbf{IC_{50}}\\) – the concentration of the GS451 drug that at which we observe 50% viability in cell culture. # read in phenotypes phenotypes <- read.table("GS451_IC50.txt", header = TRUE) head(phenotypes) ## FID IID GS451_IC50 ## 1 1001 1001 5.594256 ## 2 1002 1002 8.525633 ## 3 1003 1003 12.736739 ## 4 1004 1004 12.175201 ## 5 1005 1005 9.936742 ## 6 1006 1006 9.163483 The columns of this table are: FID & IID: Family and individual IDs of the individual GS451_IC50: Measured \\(\\mathrm{IC_{50}}\\) for the drug of interest Plot the distribution of the phenotype. ggplot(data = phenotypes, aes(x = GS451_IC50)) + geom_histogram() ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. ## Warning: Removed 1 rows containing non-finite values (stat_bin). This data looks approximately normally distributed. This is important to check because this is one of the assumptions of linear regression, which we’ll be using to perform the GWAS. "],["merging-genotype-and-phenotype-data.html", "8.10 Merging genotype and phenotype data", " 8.10 Merging genotype and phenotype data To perform a GWAS, we need to combine genotype and phenotype information for the same individuals. This means merging these two data for our SNP of interest, which we do with the merge function: # merge genotype and phenotype info for test SNP gwas_data <- merge(test_snp_gt, phenotypes, by.x = "Indiv", by.y = "IID") head(gwas_data) ## Indiv ChromKey POS gt_GT gt_GT_alleles dosage FID GS451_IC50 ## 1 1001 1 558185 0/0 A/A 0 1001 5.594256 ## 2 1002 1 558185 0/0 A/A 0 1002 8.525633 ## 3 1003 1 558185 0/0 A/A 0 1003 12.736739 ## 4 1004 1 558185 0/1 A/G 1 1004 12.175201 ## 5 1005 1 558185 0/0 A/A 0 1005 9.936742 ## 6 1006 1 558185 0/1 A/G 1 1006 9.163483 "],["gwas-for-one-variant.html", "8.11 GWAS for one variant", " 8.11 GWAS for one variant Under the hood, GWAS is just linear regression – simple statistical models to assess evidence of a relationship between two variables. We can perform this linear regression by hand, using data from the first SNP in the VCF. In our model, we’ll be asking whether there’s a relationship between an individual’s genotype (their dosage of the SNP) and phenotype (their \\(\\mathrm{IC_{50}}\\) for GS451). Why did we merge our genotype and phenotype data? When we fit linear models in the DNM module, we needed our variables (age and # of DNMs) to be separate columns of the same table. Similarly, now that our variables are genotype and phenotype, they need to be in the same dataframe. "],["genotype-phenotype-boxplots.html", "8.12 Genotype-phenotype boxplots", " 8.12 Genotype-phenotype boxplots First, let’s plot the relationship between genotype and phenotype to see if it looks interesting. Create boxplots of the phenotype, stratified by genotype of the test SNP. ggplot(data = gwas_data) + geom_boxplot(aes(x = gt_GT_alleles, y = GS451_IC50)) ## Warning: Removed 1 rows containing non-finite values (stat_boxplot). It’s unclear whether there’s a relationship here, because the phenotype distributions for these two genotypes are mostly overlapping. To be certain, we’ll now test this with linear regression. "],["linear-regression.html", "8.13 Linear regression", " 8.13 Linear regression The function to perform linear regression in R is lm(). It takes as arguments a data frame (gwas_data) and a model formula of the form outcome ~ predictors. In the case of GWAS, our outcome is the phenotype, and our predictor is the SNP genotype. We may also include covariates such as sex, age, or ancestry as additional predictors (called covariates) to control for their potential confounding effects. No such data are available here, so we just run the simple genotype vs. phenotype test. # test for association between genotype and phenotype lm(data = gwas_data, formula = GS451_IC50 ~ dosage) %>% # directly pipe (%>%) model results to the `summary()` function summary() ## ## Call: ## lm(formula = GS451_IC50 ~ dosage, data = gwas_data) ## ## Residuals: ## Min 1Q Median 3Q Max ## -5.0247 -1.9643 -0.3867 2.1967 6.6201 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 6.5712 0.3299 19.921 <2e-16 *** ## dosage 1.3846 0.6800 2.036 0.0449 * ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 2.659 on 83 degrees of freedom ## (1 observation deleted due to missingness) ## Multiple R-squared: 0.04757, Adjusted R-squared: 0.0361 ## F-statistic: 4.146 on 1 and 83 DF, p-value: 0.04493 How do we interpret the results of the linear model? The coefficient for dosage indicates that on average, each copy of the “G” allele increases \\(\\mathrm{IC_{50}}\\) by \\(1.38\\). The p-value indicates that this slope of \\(1.38\\) is significantly greater than 0 (\\(p = 0.0449\\)). Do you think this SNP would reach genome-wide significance? This p-value is borderline, sitting very close to the arbitrary cutoff of \\(0.05\\) which is generally used to determine statistical significance. If this was the only SNP that we were investigating, we might find this result promising. However, this SNP is just one of hundreds of thousands of SNPs that we will test for association, so the burden of proof will need to be much higher. Recall that the genome-wide significance threshold for GWAS in humans is \\(5 * 10^{-8}\\). "],["gwas-for-multiple-snps.html", "8.14 GWAS for multiple SNPs", " 8.14 GWAS for multiple SNPs A GWAS performs the linear regression we just did, for every SNP in the dataset. We could write a for loop to do this in R ourselves, but it would be slow because there are 256,896 variants in the full VCF. Because GWAS is such a common approach, researchers have developed software to standardize this process and make it extremely efficient. The most popular software package for GWAS is called PLINK, which is preloaded into your Cloud session. PLINK is a “command line” tool, so we could either use it by working from the Terminal tab in Posit Cloud, or using the system() command within R. For this class we’ll use the latter approach. The system() command The command line is a text interface that takes in commands for your computer’s operating system to run. RStudio and Posit Cloud are a more interactive interface for writing code that you’d normally have to run on the command line. The system() command tells RStudio to run a snippet of command line code for you, without you having to leave the R environment. "],["gwas-of-one-snp-with-plink.html", "8.15 GWAS of one SNP with PLINK", " 8.15 GWAS of one SNP with PLINK First, we’ll replicate the GWAS that we did in R with just the first SNP of the VCF, rs9699599. # replicate first SNP association with PLINK system(command = "./plink --file genotypes --linear --allow-no-sex --snp rs9699599 --pheno GS451_IC50.txt --pheno-name GS451_IC50") Breakdown of the PLINK command ./plink: Use the PLINK software --file genotypes: Genotype data files (genotypes.map, genotypes.ped) begin with the string “genotypes” --linear: Run a linear additive association test for each SNP --allow-no-sex: Include samples we don’t have sex metadata for --snp rs9699599: Only run the analysis for a single SNP (rs9699599) --pheno GS451_IC50.txt: Phenotype data is located in a file called GS451_IC50.txt --pheno-name GS451_IC50: The column heading of the phenotype to use in the phenotype file is GS451_IC50 After running PLINK, we get an output file called plink.assoc.linear. Now look at the output of the plink.assoc.linear output file that PLINK produced. snp1 <- read.table("plink.assoc.linear", header = TRUE) head(snp1) ## CHR SNP BP A1 TEST NMISS BETA STAT P ## 1 1 rs9699599 558185 G ADD 85 1.385 2.036 0.04493 How do these results compare to performing the GWAS by hand? Notice that the beta (i.e., the “slope” or coefficient) and p-value perfectly matches the results we obtained previously with R. "],["gwas-of-all-snps-with-plink.html", "8.16 GWAS of all SNPs with PLINK", " 8.16 GWAS of all SNPs with PLINK Now let’s allow PLINK to run the statistical tests for all SNPs by removing the --snp flag. system(command = "./plink --file genotypes --linear --allow-no-sex --pheno GS451_IC50.txt --pheno-name GS451_IC50") The plink.assoc.linear file should now have ~260,000 lines. Load the file into R to look at the results: results <- read.table(file = "plink.assoc.linear", header = TRUE) %>% # order table by lowest pvalue arrange(P) head(results) ## CHR SNP BP A1 TEST NMISS BETA STAT P ## 1 19 rs7257475 20372113 T ADD 88 -3.008 -6.876 9.311e-10 ## 2 19 rs10413538 20370690 T ADD 86 -3.026 -6.805 1.395e-09 ## 3 21 rs2826383 20844081 A ADD 166 3.031 5.866 2.392e-08 ## 4 19 rs12972967 20358400 T ADD 89 -2.421 -5.939 5.760e-08 ## 5 2 rs1358578 51626897 A ADD 166 2.111 5.307 3.571e-07 ## 6 17 rs3094508 33137048 C ADD 89 3.532 5.230 1.156e-06 "],["plotting-gwas-results.html", "8.17 Plotting GWAS results", " 8.17 Plotting GWAS results The qq() and manhattan() functions in the qqman package let us easily create QQ and Manhattan plots to visualize our GWAS results. # qq plot using the P (pvalues) column qq(results$P) # manhattan plot manhattan(results) SNPs with low p-values occur in peaks of multiple variants. These are not independent associations, but rather groups of variants in LD. "],["top-gwas-snp.html", "8.18 Top GWAS SNP", " 8.18 Top GWAS SNP One common future direction for GWAS studies is following up on the top SNP(s). Read in top_snp.vcf, a VCF of just the top SNP in the dataset, so that we can plot boxplots of the top SNP genotype stratified by phenotype: # extract genotypes of the top SNP top_snp <- vcfR2tidy(read.vcfR("top_snp.vcf")) ## Scanning file to determine attributes. ## File attributes: ## meta lines: 27 ## header_line: 28 ## variant count: 1 ## column count: 185 ## Meta line 27 read in. ## All meta lines processed. ## gt matrix initialized. ## Character matrix gt created. ## Character matrix gt rows: 1 ## Character matrix gt cols: 185 ## skip: 0 ## nrows: 1 ## row_num: 0 ## Processed variant: 1 ## All variants processed ## Extracting gt element GT top_snp_gt <- top_snp$gt %>% drop_na() # merge with phenotype data gwas_data <- merge(top_snp_gt, phenotypes, by.x = "Indiv", by.y = "IID") # plot boxplots ggplot(data = gwas_data) + geom_boxplot(aes(x = gt_GT_alleles, y = GS451_IC50)) ## Warning: Removed 1 rows containing non-finite values (stat_boxplot). Other potential follow-up directions include: Investigating the genomic environment in the UCSC Genome Browser Looking at nearby haplotype structure with LDproxy Note that the genotype data we’re using come from the Yoruba population Using the Geography of Genetic Variants browser to find the global allele frequencies of the variant Search for SNP in a phenotype database to see if there are other associations with it "],["conclusion-6.html", "8.19 Conclusion", " 8.19 Conclusion We used genotype and simulated phenotype data from the 1000 Genomes Project to perform a genome-wide association study for variants associated with drug \\(\\mathrm{IC_{50}}\\). Using linear regression, we first did GWAS “by hand” on just one variant in the VCF. We fit a linear model to ask whether there’s a significant relationship between genotype and phenotype. We then used PLINK to perform this test on every SNP in the genome. We followed up on the top SNP from our GWAS by plotting boxplots of phenotype stratified by genotype. "],["homework-6.html", "8.20 Homework", " 8.20 Homework 8.20.0.1 Learning Objectives Interpret results of a GWAS Practice manipulating tabular data 8.20.0.2 Assignment Run a GWAS of \\(\\mathrm{IC_{50}}\\) for the drug CB1908, using the same genotype data as before. The phenotypes are located in CB1908_IC50.txt. Make a QQ plot and a Manhattan plot of your results. Do you have any genome-wide significant hits? Are they located in or near a gene? For the top GWAS hit, plot the phenotype stratified by genotype. (Use top_snp_hw.vcf to get the genotypes of the top hit.) Solution # perform association test with PLINK system(command = "./plink --file genotypes --linear --allow-no-sex --pheno CB1908_IC50.txt --pheno-name CB1908_IC50") # read in gwas results results <- read.table(file = "plink.assoc.linear", header = TRUE) %>% mutate(index = row_number()) %>% arrange(P) # qq plot qq(results$P) # manhattan plot manhattan(results) On the Manhattan plot, there’s one hit that reaches genome-wide significance. # view top GWAS hit results[1, ] ## CHR SNP BP A1 TEST NMISS BETA STAT P ## 1 12 rs10876043 49190411 G ADD 161 1.779 7.18 2.518e-11 From looking it up in the UCSC Genome Browser, rs10876043 lies within an intron of the DIP2B gene. Finally, we plot this SNP’s genotype stratified by phenotype, using top_snp_hw.vcf. # extract top SNP and convert to tidy df top_snp <- vcfR2tidy(read.vcfR("top_snp_hw.vcf")) ## Scanning file to determine attributes. ## File attributes: ## meta lines: 27 ## header_line: 28 ## variant count: 1 ## column count: 185 ## Meta line 27 read in. ## All meta lines processed. ## gt matrix initialized. ## Character matrix gt created. ## Character matrix gt rows: 1 ## Character matrix gt cols: 185 ## skip: 0 ## nrows: 1 ## row_num: 0 ## Processed variant: 1 ## All variants processed ## Extracting gt element GT # get genotype dataframe top_snp_gt <- top_snp$gt %>% drop_na() # read in phenotype dataframe phenotypes <- read.table("CB1908_IC50.txt", header = TRUE) # merge genotype and phenotype info gwas_data <- merge(top_snp_gt, phenotypes, by.x = "Indiv", by.y = "IID") # plot genotype by phenotype boxplots ggplot(data = gwas_data) + geom_boxplot(aes(x = gt_GT_alleles, y = CB1908_IC50)) ## Warning: Removed 2 rows containing non-finite values (stat_boxplot). "],["scans-for-selection.html", "9 Scans for selection", " 9 Scans for selection In this lab, we’ll explore three methods for identifying signatures of selection: FST, population branch statistic (PBS), and extended haplotype homozygosity (EHH). 9.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Describe the genetic signatures of selection and what they reveal about the strength and timing of the selective sweep. Calculate and interpret population differentiation with FST. Understand why PBS provides additional information over two-population tests of selection. Explain how EHH and iHS leverage haplotype information to identify selection. "],["signatures-of-positive-selection.html", "9.1 Signatures of positive selection", " 9.1 Signatures of positive selection A central question in human evolutionary genetics is what genetic adaptations humans acquired as they migrated into diverse environments. Fig. 1 (source). The history of human migrations. The process of evolutionary adaptation leaves characteristic signatures on patterns of population genetic variation. By developing statistics to capture these signatures and applying them to human genetic data, we can uncover evidence of past episodes of positive selection. Statistics for identifying signatures of selection can be broadly classified into two categories: frequency-based and haplotype-based. "],["frequency-based-signatures.html", "9.2 Frequency-based signatures", " 9.2 Frequency-based signatures One signature of selection is an allele whose frequency is either smaller or larger than you would expect. Fig. 2. The allele frequencies of this variant shows large differences between population. How do we determine the expected AF? We can compare AFs between populations. On average, neutrally evolving variants should have similar frequencies across populations. We can enrich for potential targets of selection by asking which variants show the biggest population-specific frequency differences. If a variant shows large AF differences and the populations in question share common ancestry – as all populations do – then the allele frequency must have changed in one population. We can also supplement this with knowledge about when the populations diverged to determine when and how quickly this AF change must have happened. "],["haplotype-based-signatures.html", "9.3 Haplotype-based signatures", " 9.3 Haplotype-based signatures When a variant changes in frequency, it doesn’t change alone. The variants on the haplotype surrounding it will be pulled along to high frequency. This phenomenon, called hitchhiking, is similar to the haplotype blocks we observe in GWAS result (and both are caused by linkage between variants). What do you expect to happen to genetic diversity in the region of a selective sweep? If one haplotype is sweeping to high AF, we expect that genetic diversity in the region decreases because it’s being replaced by the selected haplotype. This is called a selective sweep because variation is being “swept” out of the region. This decreased diversity signature fades over time as new mutations arise on the haplotype. Fig. 3. (A) Selective sweeps reduce genetic diversity. (B)-(D) Summary of common signatures of selection. What can the size of the linked haplotype tell us about its evolutionary history? Because recombination breaks down haplotypes over time, a longer haplotype implies more recent selection. It can also provide information on the strength of selection – if most occurrences of the haplotype in the population are unbroken, selection was strong enough that it didn’t have time to recombine during the sweep. "],["setup-5.html", "9.4 Setup", " 9.4 Setup 9.4.1 R packages In addition to tidyverse and vcfR, we’ll also be using ggtree, an R package for visualizing trees associated with PBS outliers. library(tidyverse) library(vcfR) library(ggtree) "],["the-fst-statistic.html", "9.5 The FST statistic", " 9.5 The FST statistic \\(\\mathbf{F_{ST}}\\) is a statistic that quantifies differences in allele frequencies between populations at one variable site. The version of \\(\\mathrm{F_{ST}}\\) that we’ll calculate today compares genotypic variance within subpopulations (“S”) against the total population (“T”). One way to conceptualize this is the deficiency of heterozygotes observed across subpopulations, relative to the proportion that would be expected under random mating (i.e., no population structure). We calculate this by taking the difference between: \\(\\mathbf{H_T}\\): The expected frequency of heterozygotes when individuals across all subpopulations are pooled \\(\\mathbf{mean(H_S)}\\): The mean frequency of heterozygotes, calculated within each subpopulation and then averaged where \\(H = 2pq\\), and \\(p\\) and \\(q\\) are the frequencies of the two alleles at a site \\[ \\textrm{F}_{ST} = \\frac{H_T - \\textrm{mean}(H_S)}{H_T} \\] \\(\\mathrm{F_{ST}}\\) ranges from 0 to 1: \\(\\mathrm{F_{ST}} = 0\\): No population structure (separating the subpopulations doesn’t affect heterozygosity estimates) \\(\\mathrm{F_{ST}} = 1\\): Subopulations are very different (ex: one population only carries one allele, while the other population only carries the other) See this Nature Review Genetics article for a more thorough discussion on the use and interpretation of \\(\\mathrm{F_{ST}}\\) and related statistics. "],["data-for-fst.html", "9.6 Data (for FST)", " 9.6 Data (for FST) We’ll calculate \\(\\mathrm{F_{ST}}\\) using genotype data from the 1000 Genomes Project. Read in the VCF using thevcfR package: # read genotype data with vcfR vcf <- read.vcfR(file = "random_variable_sites.vcf.gz") ## Scanning file to determine attributes. ## File attributes: ## meta lines: 19 ## header_line: 20 ## variant count: 9748 ## column count: 2513 ## Meta line 19 read in. ## All meta lines processed. ## gt matrix initialized. ## Character matrix gt created. ## Character matrix gt rows: 9748 ## Character matrix gt cols: 2513 ## skip: 0 ## nrows: 9748 ## row_num: 0 ## Processed variant 1000 Processed variant 2000 Processed variant 3000 Processed variant 4000 Processed variant 5000 Processed variant 6000 Processed variant 7000 Processed variant 8000 Processed variant 9000 Processed variant: 9748 ## All variants processed We’ll also read in a metadata table with information on which populations each sample is from. # read metadata metadata <- read.table("integrated_call_samples.txt", header = TRUE) head(metadata) ## sample pop superpop sex ## 1 HG00096 GBR EUR male ## 2 HG00097 GBR EUR female ## 3 HG00099 GBR EUR female ## 4 HG00100 GBR EUR female ## 5 HG00101 GBR EUR male ## 6 HG00102 GBR EUR female "],["the-genetic_diff-function.html", "9.7 The genetic_diff function", " 9.7 The genetic_diff function We’ll compute \\(\\textrm{F}_{ST}\\) using vcfR’s genetic_diff function. (This function technically calculates \\(\\textrm{G}_{ST}\\), a version of \\(\\textrm{F}_{ST}\\) that considers when there are more than two alleles at a given locus. When a locus is biallelic, \\(\\textrm{F}_{ST} = \\textrm{G}_{ST}\\).) ?genetic_diff genetic_diff requires: vcfR object (in our case, vcf) Factor indicating populations “Factor indicating populations” The second object for genetic_diff needs to be a vector (i.e., a list) of population labels for the samples in the VCF. These labels must be factors, which is an R data type that limits a variable to a set of values. In our case, these values are the specific population labels in our dataset. We’ll be using the superpopulation groupings for this calculation. We can use our metadata table to generate a vector of superpopulation labels. Since the superpopulation IDs are in the superpop column of that dataframe, we can convert the column from character to factor values with the as.factor function. pop_labels <- as.factor(metadata$superpop) head(pop_labels) ## [1] EUR EUR EUR EUR EUR EUR ## Levels: AFR AMR EAS EUR SAS Previewing pop_labels shows us that there are five “levels” in this vector, where each level is a superpopulation name. "],["calculating-fst.html", "9.8 Calculating FST", " 9.8 Calculating FST Run genetic_diff on the VCF: # calculate gst gst_results <- genetic_diff(vcf, pop_labels) %>% # order dataframe by descending gst value arrange(-Gst) # preview highest gst variants head(gst_results) ## CHROM POS Hs_AFR Hs_AMR Hs_EAS Hs_EUR Hs_SAS ## 1 chr21 17753762 0.3537087 0.20174987 0.1326531 0.029319019 0.040063399 ## 2 chr21 18668817 0.1477089 0.38831400 0.1377374 0.424382716 0.414679179 ## 3 chr21 15620159 0.4997750 0.09318240 0.0000000 0.007905014 0.000000000 ## 4 chr21 16235733 0.4994938 0.09318240 0.0000000 0.007905014 0.002042899 ## 5 chr21 22780904 0.4992826 0.09836474 0.0000000 0.001982159 0.000000000 ## 6 chr21 22786927 0.4991001 0.09318240 0.0000000 0.001982159 0.026231489 ## Ht n_AFR n_AMR n_EAS n_EUR n_SAS Gst Htmax Gstmax ## 1 0.3650242 1320 694 1008 1008 978 0.5572530 0.8286973 0.8049790 ## 2 0.4847713 1320 694 1008 1008 978 0.4082388 0.8484665 0.6618973 ## 3 0.2439190 1320 694 1008 1008 978 0.4004813 0.8289905 0.8235999 ## 4 0.2341095 1320 694 1008 1008 978 0.3739730 0.8290489 0.8232205 ## 5 0.2323592 1320 694 1008 1008 978 0.3732539 0.8288159 0.8242912 ## 6 0.2346916 1320 694 1008 1008 978 0.3609202 0.8297041 0.8192288 ## Gprimest ## 1 0.6922578 ## 2 0.6167706 ## 3 0.4862571 ## 4 0.4542805 ## 5 0.4528180 ## 6 0.4405610 # preview lowest gst variants tail(gst_results) ## CHROM POS Hs_AFR Hs_AMR Hs_EAS Hs_EUR Hs_SAS ## 9743 chr21 45527242 0.001514004 0.000000000 0.000000000 0.001982159 0.002042899 ## 9744 chr21 46135735 0.001514004 0.000000000 0.001982159 0.000000000 0.002042899 ## 9745 chr21 10718788 0.001514004 0.000000000 0.001982159 0.001982159 0.000000000 ## 9746 chr21 43949497 0.001514004 0.002877692 0.001982159 0.000000000 0.002042899 ## 9747 chr21 33087300 0.003025712 0.005747079 0.005934666 0.003960380 0.004081616 ## 9748 chr21 7948042 0.499885216 0.499995847 0.499968506 0.499992126 0.500000000 ## Ht n_AFR n_AMR n_EAS n_EUR n_SAS Gst Htmax Gstmax ## 9743 0.001197365 1320 694 1008 1008 978 3.251980e-04 0.7924231 0.9984895 ## 9744 0.001197365 1320 694 1008 1008 978 3.251980e-04 0.7924231 0.9984895 ## 9745 0.001197365 1320 694 1008 1008 978 3.150481e-04 0.7924255 0.9984895 ## 9746 0.001596168 1320 694 1008 1008 978 2.547455e-04 0.7924784 0.9979864 ## 9747 0.004383322 1320 694 1008 1008 978 1.475473e-04 0.7930368 0.9944736 ## 9748 0.499976954 1320 694 1008 1008 978 3.141686e-05 0.8960702 0.4420513 ## Gprimest ## 9743 3.256899e-04 ## 9744 3.256899e-04 ## 9745 3.155247e-04 ## 9746 2.552595e-04 ## 9747 1.483672e-04 ## 9748 7.107064e-05 genetic_diff outputs a table of \\(\\textrm{G}_{ST}\\) results, where every line corresponds to one variant from the input VCF. Our \\(\\textrm{G}_{ST}\\) values range from \\(0.0021\\) to \\(0.00033\\). "],["distribution-of-gst-across-the-genome.html", "9.9 Distribution of GST across the genome", " 9.9 Distribution of GST across the genome Plot the distribution of \\(\\textrm{G}_{ST}\\) values from genetic_diff ggplot(data = gst_results, aes(x = Gst)) + geom_histogram() ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. This is an exponentially decaying distribution, indicating that most common human variants don’t show strong differences in allele frequency between populations. "],["top-gst-hits.html", "9.10 Top GST hits", " 9.10 Top GST hits The variants with high \\(\\textrm{G}_{ST}\\) values should show differences in allele frequency between populations. Let’s examine the top-scoring variant: gst_results[1, ] ## CHROM POS Hs_AFR Hs_AMR Hs_EAS Hs_EUR Hs_SAS Ht ## 1 chr21 17753762 0.3537087 0.2017499 0.1326531 0.02931902 0.0400634 0.3650242 ## n_AFR n_AMR n_EAS n_EUR n_SAS Gst Htmax Gstmax Gprimest ## 1 1320 694 1008 1008 978 0.557253 0.8286973 0.804979 0.6922578 We can use the GGV browser to visualize this variant’s allele frequencies across the 1000 Genomes populations. One complicating factor is that the browser is based on the hg19 reference genome, while we’re working with a VCF on the more recent hg38 coordinate system. How do you compare variants between genome builds? There are many ways of converting from genome coordinate system to the other. One way is to look up the ID of the SNP in the UCSC Genome Browser, using its chromosome and position: Fig. 4. Identifying a SNP’s rsID in the UCSC Genome Browser. This SNP has the ID rs7276293, which should be consistent between reference builds. "],["viewing-gst-hits-in-ggv.html", "9.11 Viewing GST hits in GGV", " 9.11 Viewing GST hits in GGV Now we can navigate to the GGV browser and look up the distribution of allele frequencies for this variant. Note that the “position” has changed due to the new coordinate system, but we are looking at the same SNP. This variant has huge allele frequency differences across populations, consistent with the high GST value that we computed. Also note that two populations in the Americas also carry this variant at high frequency. These are both African American populations – African Caribbean in Barbados (ACB) and African Ancestry in SW USA (ASW). Fig. 5. Allele frequencies of our top GST hit. "],["population-branch-statistic.html", "9.12 Population branch statistic", " 9.12 Population branch statistic \\(\\textrm{F}_{ST}\\) and related statistics ask about allele frequency differences between two populations. If we compare sets of three populations instead of focusing on pairs, we can calculate a different statistic called the population branch statistic (PBS). What are the advantages of comparing three populations? Two-population comparisons tell us that an allele frequency change happened after the two populations diverged, but give us no information about when it occurred. Comparing between three populations lets us contrast allele frequencies among the populations to localize frequency changes to a particular branch of a tree. Fig. 6. A variant exists at different frequencies in populations A and B. By comparing to a third population, we can identify that selection likely occurred within population A. "],["calculating-pbs.html", "9.13 Calculating PBS", " 9.13 Calculating PBS PBS is based on calculating \\(\\textrm{F}_{ST}\\) for each pairwise comparison of the three populations. We then calculate the branch length (\\(\\mathbf{T}\\)) that separates each population pair: \\[ T = -\\mathrm{log}(1 - \\textrm{F}_{ST}) \\] PBS is then computed as: \\[ \\textrm{PBS} = \\frac{\\textrm{T}_{AB} + \\textrm{T}_{AC} - \\textrm{T}_{BC}}{2} \\] "],["data-for-pbs.html", "9.14 Data (for PBS)", " 9.14 Data (for PBS) We’ll calculate PBS using data from the paper: Tucci, S. et al. (2018). Evolutionary history and adaptation of a human pygmy population of Flores Island, Indonesia.. Flores Island was home to fossils of the archaic hominin species Homo floresiensis, also called “hobbits” because their skeletons are 3 ft. tall. It’s thought that H. floresiensis lived there until just 40k-30k years ago, overlapping with modern humans. This study collected samples from individuals who currently live on Flores Island and scanned their genomes for evidence of natural selection. They calculated PBS between: The Rampasasa (RPS) population from Flores A Han Chinese (CHB) population A Melanesian population from Papua New Guinea (PNG) Fig. 7. Distribution of populations used in Tucci et al. "],["reading-in-pbs-data.html", "9.15 Reading in PBS data", " 9.15 Reading in PBS data We’ve pre-calculated pairwise \\(\\textrm{F}_{ST}\\) between the Rampasasa, Han Chinese, and Papua New Guinea populations. Load the results for chromosome 11 into R: fst_results <- read.table("fst_results.txt.gz", header = TRUE) head(fst_results) ## chr pos rps.af chb.af png.af fst.rps.chb fst.rps.png ## 1 11 100001950 0.1666670 0.0145631 0.0428571 0.32524800 0.0845486 ## 2 11 100003476 0.0555556 0.0339806 0.1000000 -0.01078610 -0.0118052 ## 3 11 100004351 0.1111110 0.0485437 0.1142860 0.05945300 -0.0322152 ## 4 11 100005864 0.6111110 0.6553400 0.4285710 -0.02752900 0.0520164 ## 5 11 100006486 0.8333330 0.7766990 0.7571430 0.00768713 -0.0119055 ## 6 11 100006861 0.5000000 0.3834950 0.2285710 0.05413630 0.1807550 ## fst.png.chb ## 1 0.00465910 ## 2 0.03640770 ## 3 0.02896550 ## 4 0.11842600 ## 5 -0.00951234 ## 6 0.06338550 Every row of this table is a SNP: Columns ending in .af contain the allele frequency for that population Columns starting with fst. contain the \\(\\textrm{F}_{ST}\\) between that population pair "],["calculating-pbs-1.html", "9.16 Calculating PBS", " 9.16 Calculating PBS Using these \\(\\textrm{F}_{ST}\\) values, we can calculate (for every SNP) the branch lengths (\\(\\mathbf{T}\\)) that separate each population pair, and then calculate PBS. The mutate() function tidyverse’s mutate function is an easy way to perform calculations on tables. Its syntax is: mutate(new_column = <formula for calculating column values>) For example, if I wanted to create a new column that average each SNP’s allele frequencies across the three populations: fst_results %>% mutate(avg_af = (rps.af + chb.af + png.af) / 3) Filling in the gaps in the code block below, use mutate to calculate T and PBS on the FST values: pbs <- fst_results %>% # calculate branch lengths between populations mutate(T_rps_chb = _________, T_rps_png = _________, T_png_chb = _________,) %>% # calculate pbs mutate(pbs = _________) %>% # sort by descending pbs value arrange(-pbs) Solution pbs <- fst_results %>% # calculate branch lengths between populations mutate(T_rps_chb = -log(1 - fst.rps.chb), T_rps_png = -log(1 - fst.rps.png), T_png_chb = -log(1 - fst.png.chb)) %>% # calculate pbs mutate(pbs = ((T_rps_png + T_rps_chb) - (T_png_chb)) / 2) %>% # sort by descending pbs value arrange(-pbs) head(pbs) ## chr pos rps.af chb.af png.af fst.rps.chb fst.rps.png fst.png.chb ## 1 11 126880301 0.833333 0.296117 0.0571429 0.734021 0.823884 0.216269 ## 2 11 126883747 0.833333 0.296117 0.0571429 0.734021 0.823884 0.216269 ## 3 11 126893266 0.833333 0.300971 0.0571429 0.729450 0.823884 0.222408 ## 4 11 126883622 0.833333 0.300971 0.0571429 0.729227 0.823884 0.221887 ## 5 11 126888750 0.833333 0.305825 0.0571429 0.724490 0.823884 0.227770 ## 6 11 126885142 0.833333 0.320388 0.0571429 0.709721 0.823884 0.244928 ## T_rps_chb T_rps_png T_png_chb pbs ## 1 1.324338 1.736612 0.2436894 1.408630 ## 2 1.324338 1.736612 0.2436894 1.408630 ## 3 1.307298 1.736612 0.2515533 1.396179 ## 4 1.306474 1.736612 0.2508835 1.396102 ## 5 1.289131 1.736612 0.2584728 1.383635 ## 6 1.236913 1.736612 0.2809422 1.346291 "],["manhattan-plot-of-pbs-results.html", "9.17 Manhattan plot of PBS results", " 9.17 Manhattan plot of PBS results We can visualize our PBS results by generating a Manhattan plot where we plot PBS on the y-axis instead of p-values. Make this Manhattan plot using geom_point. ggplot(data = pbs, aes(x = pos, y = pbs)) + geom_point() As evidence of positive selection, we are interested in both the height of the peaks in the plot, as well as the number of SNPs that comprise each peak (which is a proxy for haplotype length). "],["top-pbs-hits.html", "9.18 Top PBS hits", " 9.18 Top PBS hits What are the top PBS hits we’ve identified? Click on the pbs table to scroll through the SNPs with the highest PBS values. Use the UCSC Genome Browser to look up the top two PBS peaks. (We’re using the hg19 browser here because this data was generated with the hg19 reference genome.) What genes (if any) do these top PBS peaks overlap with? The top chr11 peak doesn’t seem to overlap with any genes, but is closest to KIRREL3. The second chr11 peak overlaps with the fatty acid desaturase gene cluster (FADS1, FADS2, and FADS3), which have previously been implicated as targets of independent episodes of positive selection in human populations. Fig. 8. The FADS gene cluster around the second PBS peak. "],["plotting-pbs-trees.html", "9.19 Plotting PBS trees", " 9.19 Plotting PBS trees Another useful way to visualize PBS is by comparing trees for the top PBS outliers to the genome-wide average tree. Run the code blocks below to plot these trees: # create average tree tr_mean <- rtree(n = 3, rooted = FALSE, br = c(mean(pbs$T_rps_png), mean(pbs$T_rps_chb), mean(pbs$T_png_chb))) # plot average tree ggtree(tr_mean, layout = "daylight") + geom_treescale(width = 0.1) + geom_tiplab(label = c("RPS", "PNG", "CHB")) ## Average angle change [1] 0.407407407407407 ## Average angle change [2] 0 # create tree for top snp tr_top <- rtree(n = 3, rooted = FALSE, br = c(pbs[1,]$T_rps_png, pbs[1,]$T_rps_chb, pbs[1,]$T_png_chb)) # plot top snp tree ggtree(tr_top, layout = "daylight") + geom_treescale(width = 0.1) + geom_tiplab(label = c("RPS", "PNG", "CHB")) ## Average angle change [1] 0.407407407407407 ## Average angle change [2] 0 "],["extended-haplotype-homozygosity.html", "9.20 Extended haplotype homozygosity", " 9.20 Extended haplotype homozygosity The haplotype-based class of selection statistics quantifies long haplotypes that result from a selective sweep. Extended haplotype homozygosity (EHH) is defined as the probability that any two haplotypes in a population are homozygous at SNPs in specific genomic region. EHH should be elevated in regions under historical selection, because a sweep causes one haplotype to rise to high frequency, and decay as you move further from the site under selection. Fig. 9. EHH measures how likely two haplotypes are to carry the same variant at a given location – a signature that we expect recent selection to exaggerate. "],["plotting-ehh.html", "9.21 Plotting EHH", " 9.21 Plotting EHH EHH can be visualized with phylogeny-like plots like the one below. The width of the blue bar (the haplotype of interest) represents the haplotype’s frequency in a population, and the steps in the plot indicate historical recombination. The other branches of the phylogeny (in red) indicate other haplotypes in this region. An overrepresentation of one haplotype over the others creates the observation of extreme EHH. Fig. 10 (from David Reich). Overrepresentation of the blue haplotype indicates extreme EHH, a possible signature of selection. EHH plot for real data This plot shows EHH calculated for the CEU population of 1000 Genomes (Utah Residents [CEPH] with Northern and Western European Ancestry), zoomed in at the lactase (LCT) locus. A haplotype in this locus underwent a selective sweep in ancestor of European populations that allowed digestion of milk into adulthood, resulting in a present-day signature of EHH that stretches across megabases of sequence. In contrast, the ancestral haplotype (bottom) displays a much greater diversity and recombination. Fig. 11. EHH calculated for the lactase locus. "],["integrated-haplotype-statistic.html", "9.22 Integrated haplotype statistic", " 9.22 Integrated haplotype statistic If you calculate EHH for both the new and ancestral haplotypes at a locus, you can compare them to calculate the integrated haplotype statistic (iHS), which is the ratio of the area under the EHH curve for the derived and ancestral haplotypes. Fig. 12. Comparing the EHH of haplotypes carrying the derived and ancestral alleles to calculate iHS. "],["the-pophuman-browser.html", "9.23 The PopHuman browser", " 9.23 The PopHuman browser While some R packages exist to compute EHH and iHS (e.g., the rehh package), they require some tricky processing of VCF files. Moreover, these statistics have already been computed genome-wide for all of the populations in the 1000 Genomes dataset, available from the PopHuman browser. This browser lets you pull up results for several population genetic signatures. Look up the lactase (LCT) gene in the search bar, and then click Select tracks in the upper left-hand corner to choose: iHS for the CEU (European) population pi for the CEU population. This is a measure of nucleotide diversity, which we expect to be low in a region under historical selection Fig. 13. iHS and \\(\\pi\\) in the LCT region. Note that if we compare both of these statistics to the genome-wide mean (yellow lines), we can see how dramatically they deviate from expectations in this genomic region. "],["conclusion-7.html", "9.24 Conclusion", " 9.24 Conclusion In this lab, we used three approaches to identify selection in multi-population sequencing data. Using genotype data from the 1000 Genomes Project, we calculated FST, a measure of how different a variant’s allele frequency is between populations. We confirmed in the GGV Browser that the top FST variant shows strong population-specific AF differences. We then calculated the population branch statistic (PBS) to identify variants under selection in a human population on Flores Island, Indonesia. One of the top PBS hits was in the fatty acid desaturase gene cluster (FADS). Finally, we discussed extended haplotype homozygosity (EHH) and related statistics, which detect long haplotypes that result from a selective sweep. Using the PopHuman browser, we saw that the LCT locus – the most famous example of selection in humans – exhibits both elevated EHH and reduced genetic diversity (\\(\\pi\\)). "],["homework-7.html", "9.25 Homework", " 9.25 Homework 9.25.0.1 Learning Objectives Interpret multiple statistics for measuring selection Explain how specific statistics can give different results because they measure different genetic signatures 9.25.0.2 Assignment Read this review paper on genomic evidence of human local adaptation by Fan et al. Find examples of local adaptation (genes and populations) in the paper, and look up the relevant populations (or related populations) and tests of selection in the PopHuman browser. Are the signatures of selection apparent? Are the signature apparent based on all statistics? Why do certain statistics capture evidence of selection at certain loci but not others? "],["archaic-admixture.html", "10 Archaic admixture", " 10 Archaic admixture In this lab, we’ll discuss three common statistics, \\(D\\), \\(f_{4}\\), and the \\(f_{4}\\)-ratio, which are used for quantifying and testing hypotheses related to admixture (or “introgression”). 10.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Explain how incomplete lineage sorting can create patterns of allele sharing that are discordant with species relationships. Describe how introgression is expected to affect patterns of allele sharing. Interpret the \\(D\\) and \\(f_4\\) statistics and their associated p-values. Interpret the \\(f_{4}\\)-ratio ratio statistic and whether it implies differences in archaic admixture between populations. "],["neanderthal-and-denisovan-introgression.html", "10.1 Neanderthal and Denisovan introgression", " 10.1 Neanderthal and Denisovan introgression As modern humans migrated out of Africa 50,000-70,000 years ago, they encountered and intebred with two groups of archaic hominins, the Neanderthals and Denisovans. Admixture with archaic hominins resulted in introgression of archaic DNA into these migrating populations. These Neanderthal and Denisovan sequences still persist in the genomes of their present-day descendents. Fig. 1. Ancient encounters between migrating human populations and archaic hominins. "],["inferring-introgression-from-phylogenetic-trees.html", "10.2 Inferring introgression from phylogenetic trees", " 10.2 Inferring introgression from phylogenetic trees One test for introgression – called the \\(\\textbf{D}\\) statistic, or ABBA-BABA test – compares the phylogenetic tree of species-level relationships with the tree for a specific genetic variant. We expect the species-level tree for Neanderthals and humans to look like the white bars of the tree in Fig. 2, where any two human populations are more similar to each other than they are to Neanderthals or chimpanzees (the outgroup). If a genetic variant differs between humans and Neanderthals, we generally expect it to segregate according to the species-level tree, in an AABB pattern (Fig. 2). Fig. 2. A variant concordant with the species-level tree for modern humans and Neanderthals. "],["incomplete-lineage-sorting.html", "10.3 Incomplete lineage sorting", " 10.3 Incomplete lineage sorting More rarely, the tree constructed for a specific SNP is discordant with the species tree. This is usually due to incomplete lineage sorting (ILS) – when genetic variation is present in the ancestor of two populations (e.g., the modern human–Neanderthal ancestor), then randomly fixes in a fashion that happens to conflict with the populations’ evolutionary relationships. ILS can create discordant ABBA or BABA trees for a given SNP. Under ILS, we would expect to see approximately equal numbers of ABBA and BABA trees. Fig. 3. ABBA and BABA allele patterns can be formed by incomplete lineage sorting. "],["evidence-of-introgression.html", "10.4 Evidence of introgression", " 10.4 Evidence of introgression Discordant trees can also be produced by introgression. In this case, the B allele arises on the Neanderthal lineage and is passed from Neanderthals into a human population, creating either an ABBA or BABA pattern (depending on which population receives Neanderthal gene flow). Fig. 4. ABBA and BABA allele patterns formed by Neanderthal introgression. "],["the-d-statistic.html", "10.5 The \\(D\\) statistic", " 10.5 The \\(D\\) statistic Introgression creates an imbalance in the number of ABBA or BABA trees if only one of the human populations has admixed with Neanderthals. The \\(\\textbf{D}\\) statistic quantifies this imbalance: \\[ D = \\frac{\\textrm{# BABA sites} - \\textrm{# ABBA sites}}{\\textrm{# BABA sites} + \\textrm{# ABBA sites}} \\] \\(D > 0\\) is evidence for Neanderthal gene flow into the H2 population, while \\(D < 0\\) is evidence for gene flow into H1. Choice of populations for the \\(D\\) statistic The choice of populations is very important when calculating the \\(D\\) statistic. When assessing archaic introgression, H2 is typicaly set as a human population without archaic admixture (e.g., a population from Africa). If H2 instead were a European population that did possess introgressed sequence, we would not expect a significant \\(D\\) statistic. "],["setup-6.html", "10.6 Setup", " 10.6 Setup In this lab, we’ll quantify evidence for introgression in human populations using \\(D\\) and related statistics. 10.6.1 R packages In addition to tidyverse, we’ll use the admixr package, which allows us to easily run the software package ADMIXTOOLS from within R to calculate \\(D\\) and related statistics. The exercises for class were adapted from the admixr tutorial, available here. library(tidyverse) library(admixr) "],["data-3.html", "10.7 Data", " 10.7 Data The admixr package provides real example data from 10 human individuals, which can be acquired by running its download_data() function: # download data into current directory prefix <- download_data(dirname = ".") We now have a directory called snps that contain four files: snps.geno: Genotype of each individual (column) at each SNP (row) Represented as counts of the alternative allele (0, 1, 2) snps.ind: Population IDs for each individual snps.snp: SNP IDs, positions, and alleles regions.bed: A file of genomic regions (not required for basic admixr analysis) EIGENSTRAT format Together, the three .geno, .ind, and .snp files constitute EIGENSTRAT format. This is just a way of representing genotype data, similar to a VCF – in fact, several software packages exist to convert between VCF and EIGENSTRAT. "],["reading-in-data.html", "10.8 Reading in data", " 10.8 Reading in data We can provide the location of the downloaded files to the eigenstrat() function, which then constructs an EIGENSTRAT object to be used for downstream analysis. # read in eigenstrat files snps <- eigenstrat(prefix) snps ## EIGENSTRAT object ## ================= ## components: ## ind file: ./snps/snps.ind ## snp file: ./snps/snps.snp ## geno file: ./snps/snps.geno "],["the-d-function.html", "10.9 The d() function", " 10.9 The d() function admixr computes the \\(D\\) statistic in a function called d(). ?d As input, d() asks for: Data object in EIGENSTRAT format Four population names (W, X, Y, Z) to calculate D between "],["computing-the-d-statistic.html", "10.10 Computing the D statistic", " 10.10 Computing the D statistic Let’s compute \\(D\\) for four of the individuals we have data for: French, Sardinian, Vindija (Neanderthal), and chimpanzee. d_result <- d(data = snps, # provide population names to calculate D between W = "French", X = "Sardinian", Y = "Vindija", Z = "Chimp") d_result ## W X Y Z D stderr Zscore BABA ABBA nsnps ## 1 French Sardinian Vindija Chimp 0.0038 0.0074 0.511 10974 10891 487843 How do we interpret these results? The last three columns count the number of ABBA and BABA sites, as well as the total number of variants being analyzed. First, note that the ABBA/BABA sites are only a small fraction of the total number of variants – most variants conform to the species-level tree. The number of ABBA and BABA variants also looks similar, which implies that the discordant trees in these four populations primarily result from ILS rather than introgression. The middle columns give the actual value of \\(D\\) and its standard error, as well as the Z score (which is equal to \\(\\frac{D}{\\textrm{stderr}}\\)). "],["converting-to-p-values.html", "10.11 Converting to p-values", " 10.11 Converting to p-values How do we know whether the ABBA-BABA counts are significantly different? We can convert the Z score into a p-value: d_result <- d_result %>% # convert z score into pvalue mutate(p = 2 * pnorm(-abs(Zscore))) d_result ## W X Y Z D stderr Zscore BABA ABBA nsnps ## 1 French Sardinian Vindija Chimp 0.0038 0.0074 0.511 10974 10891 487843 ## p ## 1 0.6093511 Interpretation of this p-value The p-value does not look significant (no introgression into the ancestors of this French or Sardinian individual). This is in line with our observation that there doesn’t seem to be a disproportionate amount of ABBA or BABA sites. "],["computing-d-for-all-populations.html", "10.12 Computing D for all populations", " 10.12 Computing D for all populations We can give d() a list of populations to compute the \\(D\\) statistic for, where: W: A vector of our populations of interest X: An assumed unadmixed population (Yoruba) Y: The introgressing population (Vindija Neanderthal) Z: Outgroup (chimpanzee) # create vector of populations of interest pops <- c("French", "Sardinian", "Han", "Papuan", # including three African populations "Khomani_San", "Mbuti", "Dinka") # calculate D d_result <- d(data = snps, W = pops, X = "Yoruba", Y = "Vindija", Z = "Chimp") %>% # convert z score into pvalue mutate(p = 2 * pnorm(-abs(Zscore))) d_result ## W X Y Z D stderr Zscore BABA ABBA nsnps ## 1 French Yoruba Vindija Chimp 0.0313 0.006933 4.510 15802 14844 487753 ## 2 Sardinian Yoruba Vindija Chimp 0.0287 0.006792 4.222 15729 14852 487646 ## 3 Han Yoruba Vindija Chimp 0.0278 0.006609 4.199 15780 14928 487925 ## 4 Papuan Yoruba Vindija Chimp 0.0457 0.006571 6.953 16131 14721 487694 ## 5 Khomani_San Yoruba Vindija Chimp 0.0066 0.006292 1.051 16168 15955 487564 ## 6 Mbuti Yoruba Vindija Chimp -0.0005 0.006345 -0.074 15751 15766 487642 ## 7 Dinka Yoruba Vindija Chimp -0.0009 0.006124 -0.151 15131 15159 487667 ## p ## 1 6.482763e-06 ## 2 2.421441e-05 ## 3 2.680963e-05 ## 4 3.575987e-12 ## 5 2.932586e-01 ## 6 9.410104e-01 ## 7 8.799757e-01 Interpretation of \\(D\\) results This is the result that was published in Green et al. 2010, revealing evidence for gene flow from Neanderthals into the ancestors of non-African populations. We see significant evidence of Neanderthal introgression into the genomes of the non-African samples (French, Sardinian, Han, Papuan), but not the African samples (although we know from recent research that this is an oversimplification). "],["plotting-the-d-statistic.html", "10.13 Plotting the D statistic", " 10.13 Plotting the D statistic Use this code to plot the \\(D\\) statistic and standard error calculated for each population. This is a visual representation of the data in the d_result table: ggplot(data = d_result, aes(x = W, y = D, color = p < 0.05)) + geom_point() + geom_hline(yintercept = 0, linetype = 2) + geom_errorbar(aes(ymin = D - 1.96 * stderr, ymax = D + 1.96 * stderr), width = 0.5) + xlab("Population") "],["f_4-statistic.html", "10.14 \\(f_{4}\\) statistic", " 10.14 \\(f_{4}\\) statistic The \\(\\mathbf{f_{4}}\\) statistic – not to be confused with the \\(\\mathrm{F_{ST}}\\) from the previous week – is very similar to the D statistic. Its main advantage is that it is proportional to the branch length separating two pairs of populations. Compute the \\(f_{4}\\) statistic for all populations using the code below: f4_result <- f4(data = snps, W = pops, X = "Yoruba", Y = "Vindija", Z = "Chimp") %>% # convert z score into pvalue mutate(p = 2 * pnorm(-abs(Zscore))) f4_result ## W X Y Z f4 stderr Zscore BABA ABBA nsnps ## 1 French Yoruba Vindija Chimp 0.001965 0.000437 4.501 15802 14844 487753 ## 2 Sardinian Yoruba Vindija Chimp 0.001798 0.000427 4.209 15729 14852 487646 ## 3 Han Yoruba Vindija Chimp 0.001746 0.000418 4.178 15780 14928 487925 ## 4 Papuan Yoruba Vindija Chimp 0.002890 0.000417 6.924 16131 14721 487694 ## 5 Khomani_San Yoruba Vindija Chimp 0.000436 0.000415 1.051 16168 15955 487564 ## 6 Mbuti Yoruba Vindija Chimp -0.000030 0.000410 -0.074 15751 15766 487642 ## 7 Dinka Yoruba Vindija Chimp -0.000057 0.000380 -0.151 15131 15159 487667 ## p ## 1 6.763451e-06 ## 2 2.565034e-05 ## 3 2.940837e-05 ## 4 4.390659e-12 ## 5 2.932586e-01 ## 6 9.410104e-01 ## 7 8.799757e-01 Note that the p-values are the same as when we calculated the \\(D\\) statistic, but the actual \\(f_4\\) values are different. "],["f_4-ratio-statistic.html", "10.15 \\(f_{4}\\)-ratio statistic", " 10.15 \\(f_{4}\\)-ratio statistic The branch length proportionality of the \\(f_4\\) statistic is useful for deriving yet another statistic, called the \\(\\mathbf{f_{4}}\\)-ratio statistic. As implied by its name, this simply a ratio of two different \\(f_{4}\\) statistics. Unlike \\(D\\) and \\(f_{4}\\), the \\(f_{4}\\)-ratio tells us how much Neanderthal ancestry a given individual possesses. Calculate the \\(f_{4}\\)-ratio using the code block below: f4_ratio_result <- f4ratio(data = snps, X = pops, A = "Altai", B = "Vindija", C = "Yoruba", O = "Chimp") %>% # convert z score to pvalue mutate(p = 2 * pnorm(-abs(Zscore))) f4_ratio_result ## A B X C O alpha stderr Zscore p ## 1 Altai Vindija French Yoruba Chimp 0.023774 0.006176 3.850 1.181178e-04 ## 2 Altai Vindija Sardinian Yoruba Chimp 0.024468 0.006071 4.031 5.554004e-05 ## 3 Altai Vindija Han Yoruba Chimp 0.022117 0.005892 3.754 1.740349e-04 ## 4 Altai Vindija Papuan Yoruba Chimp 0.037311 0.005812 6.420 1.362743e-10 ## 5 Altai Vindija Khomani_San Yoruba Chimp 0.003909 0.005913 0.661 5.086123e-01 ## 6 Altai Vindija Mbuti Yoruba Chimp 0.000319 0.005717 0.056 9.553418e-01 ## 7 Altai Vindija Dinka Yoruba Chimp -0.001500 0.005394 -0.278 7.810124e-01 For this statistic, alpha represents the proportion of the genome whose ancestry traces to Neanderthal introgression. "],["plotting-f_4-ratio-results.html", "10.16 Plotting \\(f_{4}\\)-ratio results", " 10.16 Plotting \\(f_{4}\\)-ratio results Run the code below to plot the \\(f_{4}\\)-ratio values we computed: ggplot(data = f4_ratio_result, aes(x = X, y = alpha, color = p < 0.05)) + geom_point() + geom_errorbar(aes(ymin = alpha - 2 * stderr, ymax = alpha + 2 * stderr), width = 0.5) + geom_hline(yintercept = 0, linetype = 2) + labs(y = "Neanderthal ancestry proportion", x = "Present-day individual") Based on what we know about Papuan populations, do you think the estimate of 4% Neanderthal introgressed DNA is accurate? We know that Oceanian populations also experienced introgression from Denisovans. Denisovans were more genetically similar to Neanderthals than to modern humans, so Denisovan ancestry is being counted as Neanderthal ancestry by this metric. "],["computing-statistics-in-genomic-intervals.html", "10.17 Computing statistics in genomic intervals", " 10.17 Computing statistics in genomic intervals We’ve so far computed the \\(D\\), \\(f_4\\), and \\(f_4\\)-ratio statistics across the entire genome, but we can also restrict computation to particular genomic intervals, such as genes, promoters, enhancers, etc. What would region-specific differences imply? Region-specific differences suggest that there are some regions of the genome that are particularly tolerant or intolerant to introgression. Fig. 5 (source). Proportion of introgressed Neanderthal ancestry within specific gene annotations. In the figure below, we see that the genome-wide average percentage of Neanderthal ancestry is ~2%, but there are some genomic regions (promoters, evolutionarily conserved sequences) where this percentage is lower. One theory explaining this pattern is that Neanderthals accumulated a genetic load of slightly deleterious mutations due to their small population sizes. Consequently, when Neanderthal sequences were introgressed into human populations, they were subjected to negative selection, which was stronger in more functionally important regions of the genome. "],["bed-files.html", "10.18 BED files", " 10.18 BED files Annotations of genomic intervals are commonly represented in a file format called BED. We can utilize these files in admixr’s filter_bed() function, which excludes or restricts analyses to genomic intervals within a BED file. Run the code below to re-calculate the \\(f_4\\)-ratio with promoters_hg19.bed – a bed file containing the coordiinates for promoters annotated in the Ensembl Regulatory Build. We can create a new snps data object that either keeps or excludes these regions from our analysis. # get the path to the `regions.bed` file bed <- file.path("promoters_hg19.bed") # option 1: KEEP only these regions for analysis new_snps_keep <- filter_bed(snps, bed) # option 2: REMOVE these regions from analysis new_snps_remove <- filter_bed(snps, bed, remove = TRUE) "],["region-specific-f_4-ratio.html", "10.19 Region-specific \\(f_4\\) ratio", " 10.19 Region-specific \\(f_4\\) ratio Now we can re-calculate the \\(f_4\\)-ratio only within promoter regions. # f4-ratio with only promoters f4_filtered <- f4ratio(data = new_snps_keep, X = pops, A = "Altai", B = "Vindija", C = "Yoruba", O = "Chimp") %>% # convert z score to pvalue mutate(p = 2 * pnorm(-abs(Zscore))) f4_filtered ## A B X C O alpha stderr Zscore p ## 1 Altai Vindija French Yoruba Chimp -0.005541 0.028515 -0.194 0.84617588 ## 2 Altai Vindija Sardinian Yoruba Chimp 0.002263 0.031027 0.073 0.94180612 ## 3 Altai Vindija Han Yoruba Chimp 0.066668 0.029767 2.240 0.02509092 ## 4 Altai Vindija Papuan Yoruba Chimp 0.010940 0.030057 0.364 0.71585801 ## 5 Altai Vindija Khomani_San Yoruba Chimp 0.026367 0.031975 0.825 0.40937159 ## 6 Altai Vindija Mbuti Yoruba Chimp 0.005176 0.030194 0.171 0.86422377 ## 7 Altai Vindija Dinka Yoruba Chimp 0.008542 0.026768 0.319 0.74972651 Plot the region-excluded \\(f_4\\)-ratios ggplot(f4_filtered, aes(x = X, y = alpha, color = p < 0.05)) + geom_point() + geom_errorbar(aes(ymin = alpha - 2 * stderr, ymax = alpha + 2 * stderr), width = 0.5) + geom_hline(yintercept = 0, linetype = 2) + labs(y = "Neanderthal ancestry proportion", x = "Present-day individual") Except for the Han population, we see almost no Neanderthal ancestry when we calculate the \\(f_4\\)-ratio within promoters – supporting the idea that functionally important genomic regions are depleted for Neanderthal introgression. "],["conclusion-8.html", "10.20 Conclusion", " 10.20 Conclusion In this lab, we assessed evidence for Neanderthal introgression into specific human populations. We reviewed the \\(\\mathbf{D}\\) statistic, which asks whether a variant shows an imbalance in the population inheritance patterns expected from incomplete lineage sorting (ILS). Such an imbalance implies historical introgression into one population. With admixr, we calculated the \\(D\\) statistic for one individual from each of seven modern human populations, identifying significant evidence for Neanderthal introgression into the ancestors of non-African – but not African – populations. We also calculated the \\(\\mathbf{f_4}\\) statistic, which is very similar to the \\(D\\) statistic but is proportional to the genetic distance between two populations. We computed the \\(\\mathbf{f_4}\\)-ratio, whose value indicates the proportion of introgressed ancestry in each population. Finally, we computed the \\(\\mathbf{f_4}\\)-ratio within just promoter regions, where we observed a depletion of Neanderthal ancestry. "],["homework-8.html", "10.21 Homework", " 10.21 Homework 10.21.0.1 Learning Objectives Practice calculating introgression statistics in admixr Interpret the biological significance of region-specific values of the \\(f_4\\)-ratio 10.21.0.2 Assignment Follow these steps to create your own genome stratifications for calculating the \\(f_4\\) ratio statistic. Go to the UCSC Table Browser, where you can find a wide selection of annotations for the human genome. Make sure you set the assembly: drop-down box to Feb. 2009 (GRCh37/hg19). Use the group: and track: menus to select any set of genomic regions. You can click the data format description button and scroll to the Description section to find out what each annotation represents. Under the Retrieve and display data section, set the output format: to BED. Enter an output filename: (ex: all_genes.bed). Click get output to download the file. In Posit Cloud, upload your file using the Upload button in the Files panel (bottom right). Run the code block below to reformat the BED file. The code matches the UCSC’s chromosome naming format with the format used in the snps data: # fill in blank with the name of your bed file system(command = "sed -i 's/chr//g' ________") # get the path to your bed file bed <- file.path("________") Compute the \\(f_4\\) ratio statistic within and outside of the genomic intervals. Repeat for another set of genome annotations to contrast Neanderthal ancestry in different genomic elements. Solution Download tracklist of haploinsufficient genes (Phenotype and Literature -> Haploinsufficiency). # get the path to the `regions.bed` file bed <- file.path("haploinsufficient.bed") # option 1: KEEP only these regions for analysis new_snps_keep <- filter_bed(snps, bed) # option 2: REMOVE these regions from analysis new_snps_remove <- filter_bed(snps, bed, remove = TRUE) Re-calculate the \\(f_4\\)-ratio: # f4-ratio with the regions kept f4_keep <- f4ratio(data = new_snps_keep, X = pops, A = "Altai", B = "Vindija", C = "Yoruba", O = "Chimp") %>% # convert z score to pvalue mutate(p = 2 * pnorm(-abs(Zscore))) f4_keep ## A B X C O alpha stderr Zscore p ## 1 Altai Vindija French Yoruba Chimp 0.030580 0.009385 3.258 1.122004e-03 ## 2 Altai Vindija Sardinian Yoruba Chimp 0.018057 0.009117 1.981 4.759127e-02 ## 3 Altai Vindija Han Yoruba Chimp 0.023127 0.009617 2.405 1.617247e-02 ## 4 Altai Vindija Papuan Yoruba Chimp 0.036462 0.008964 4.068 4.741838e-05 ## 5 Altai Vindija Khomani_San Yoruba Chimp -0.001223 0.008774 -0.139 8.894501e-01 ## 6 Altai Vindija Mbuti Yoruba Chimp -0.015781 0.009100 -1.734 8.291808e-02 ## 7 Altai Vindija Dinka Yoruba Chimp -0.004929 0.008235 -0.599 5.491729e-01 # f4-ratio with the regions removed f4_remove <- f4ratio(data = new_snps_remove, X = pops, A = "Altai", B = "Vindija", C = "Yoruba", O = "Chimp") %>% # convert z score to pvalue mutate(p = 2 * pnorm(-abs(Zscore))) f4_remove ## A B X C O alpha stderr Zscore p ## 1 Altai Vindija French Yoruba Chimp 0.016554 0.007929 2.088 3.679783e-02 ## 2 Altai Vindija Sardinian Yoruba Chimp 0.027980 0.007826 3.575 3.502279e-04 ## 3 Altai Vindija Han Yoruba Chimp 0.020285 0.007348 2.761 5.762468e-03 ## 4 Altai Vindija Papuan Yoruba Chimp 0.036136 0.007550 4.786 1.701381e-06 ## 5 Altai Vindija Khomani_San Yoruba Chimp 0.005713 0.007593 0.752 4.520511e-01 ## 6 Altai Vindija Mbuti Yoruba Chimp 0.009803 0.007233 1.355 1.754176e-01 ## 7 Altai Vindija Dinka Yoruba Chimp -0.000663 0.006798 -0.097 9.227264e-01 Some of the alpha values for each population change when excluding/restricting to haploinsufficient genes, but their standard error ranges still overlap between the two \\(f_4\\)-ratio calculations, so they likely aren’t truly different. "],["gene-expression.html", "11 Gene expression", " 11 Gene expression In this lab, we’ll use data from the Genotype-Tissue Expression (GTEx) Project to explore how genetic variation impacts gene expression. 11.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Define expression and splicing quantitative trait loci. Explain the challenge of multiple testing in eQTL studies and how it is typically handled. Navigate the GTEx Portal to find expression data for genes of interest. "],["gene-expression-1.html", "11.1 Gene expression", " 11.1 Gene expression In this class, we’ve mostly discussed variation at the level of DNA sequence. However, variation in gene expression – and how it interacts with genotype data – is an equally important aspect of phenotype diversity. Measuring gene expression Sequencing mRNA molecules (RNA sequencing), aligning them to a reference genome, and counting the reads per gene provides us with a proxy for measuring expression level. Fig. 1 (source). Counting transcript expression from RNA-seq reads. "],["the-genotype-tissue-expression-project.html", "11.2 The Genotype-Tissue Expression project", " 11.2 The Genotype-Tissue Expression project In 2010, the NIH launched the first large-scale dataset of gene expression data, called the Genotype-Tissue Expression (GTEx) project. The final version of this dataset (v8) was released in 2020. GTEx is currently the most comprehensive gene expression dataset in existence. It involved the sequencing of whole genomes (DNA-seq) as well as transcriptomes (RNA-seq) from 948 recently-deceased individuals, with up to 54 tissues sampled throughout their bodies. One of the main motivations of GTEx was to better understand the genetic control of gene expression. How does genetic variation contribute to variation in amount, splicing, and tissue specificity of expressed RNA? Fig. 2 (source). Summary of individuals sequenced by GTEx. "],["gtex-portal.html", "11.3 GTEx portal", " 11.3 GTEx portal The GTEx Portal provides an interface to summarize and visualize these data. In the search bar, we can look up a gene of interest and see: Violin plots depicting inter-individual variation in gene expression across all tissues Variants that impact expression or splicing of that gene Fig. 3 (source). Distributions of gene expression across tissues for the DNMT3A gene. "],["genetic-effects-on-gene-expression.html", "11.4 Genetic effects on gene expression", " 11.4 Genetic effects on gene expression Why does expression for the same gene vary across individuals? There are many factors that can contribute to variability in gene expression in a population: Environment (ex: diet, climate, disease) Stochasticity/noise Epigenetics (methylation, repressive/activating histone marks) Genetics (genetic variants in promoter, enhancer, etc. sequences) How do we discover genetic variants that influence gene expression? We can perform a genome-wide association study, similar to what we would do for an organismal phenotype like height. This time, our phenotype is the expression of a specific gene, and we can search for genetic variants that impact this expression. "],["expression-qtls.html", "11.5 Expression QTLs", " 11.5 Expression QTLs The variants we identify with this GWAS approach are called expression quantitative trait loci (eQTLs). Notably, because the number of phenotypes we have is equal to the number of genes we’re testing, we would have to perform ~20,000 GWASs (the number of gemes) for every eQTL study in humans, and test ~5 million SNPs per GWAS. Multiple testing in eQTL studies When we’re performing this many repeated tests, you run the risk that any hits you find are just due to chance. In a GWAS, we would use multiple testing correction to account for this. However, because of the overwhelming number of tests we need to perform to identify eQTLs, our significance threshold would be so low that we likely wouldn’t discover anything. Reducing the number of tests In order to reduce the number of tests, we typically focus on eQTL mapping just in in the region around the gene body, which dramatically decreases the number of SNPs we’re testing. The rationale for this approach is that nearby regulatory regions (promoters, enhancers, etc.) are more likely to influence expression. Fig. 4. eQTL studies typically restrict their QTL search space to variants within 1 Mb of the gene. "],["eqtls-in-the-gtex-portal.html", "11.6 eQTLs in the GTEx Portal", " 11.6 eQTLs in the GTEx Portal The GTEx Portal includes an option to view all significant eQTLs for a gene, below the plots of tissue expression. Note that these eQTLs are labeled by tissue – they may not impact transcription outside of that tissue. Fig. 5. Significant eQTLs for DNMT3A in the GTEx Portal. eQTL violin plots The Actions column provides quick access to several visualizations of each eQTL, including a violin plot that shows how it impacts expression: Fig. 6. The T allele at the chr2_25264228_C_T_b38 SNP decreases DNMT3A expression. "],["splicing-qtls.html", "11.7 Splicing QTLs", " 11.7 Splicing QTLs In addition to variants that impact gene expression, there are splicing quantitative trait loci (sQTLs) that alter how a gene is spliced. Some sQTL mechanisms include: Create or destroying a splicing donor/acceptor site Changing the binding site for a protein that regulates splicing Altering a splicing factor protein itself Fig. 7. sQTLs may alter splice donor/acceptor sites, or binding sites for transcription factors that regulate splicing. sQTLs in GTEx The GTEx Portal also provides a list of sQTLs for each gene. Note that the violin plots for these QTLs refer to a specific intron of DNMT3A whose inclusion rate is affected by each SNP. Fig. 8. The A allele at the chr2_25530386_G_A_b38 SNP reduces excision of the chr2:25246776:25247051:clu_42604 intron of DNMT3A. "],["setup-7.html", "11.8 Setup", " 11.8 Setup Now we’ll look at the GTEx data ourselves to perform our own gene expression analyses. 11.8.1 R packages In addition to tidyverse, we’ll also load the MASS package, which is useful for various statistical functions. library(tidyverse) library(MASS) "],["data-4.html", "11.9 Data", " 11.9 Data The GTEx Portal provides links for downloading curated and summarized forms of its data, including giant matrices that encode the expression of every gene across all samples and tissues. For ease of manipulation in R, we’ve subset this data to 150 samples, highly expressed genes, and only data from liver and lung tissue. gtex <- read.table("gtex_subset.txt.gz", header = TRUE) head(gtex) ## Sample Age Sex Death_Hardy Tissue Gene_ID Gene_Name Counts ## 1 GTEX-111YS 60-69 M 0 Lung ENSG00000187634.11 SAMD11 59 ## 2 GTEX-111YS 60-69 M 0 Lung ENSG00000188976.10 NOC2L 2789 ## 3 GTEX-111YS 60-69 M 0 Lung ENSG00000187961.13 KLHL17 716 ## 4 GTEX-111YS 60-69 M 0 Lung ENSG00000187583.10 PLEKHN1 47 ## 5 GTEX-111YS 60-69 M 0 Lung ENSG00000187642.9 PERM1 23 ## 6 GTEX-111YS 60-69 M 0 Lung ENSG00000188290.10 HES4 534 The columns of this dataframe are: Sample: Individual sequenced Age: Individual’s age range Sex: Individual’s sex Death_Hardy: Individual’s cause of death, measured on the Hardy Scale Tissue: Tissue measured Gene_ID: Ensembl gene ID Gene_Name: The common gene name Counts: Expression level for the gene Ex: GTEX-111YS has 59 sequencing reads that mapped to the SAMD11 gene Data normalization The expression levels in this table have been normalized to account for factors such as sequencing variation between samples – i.e., if we collected more sequencing data from one individual than another. "],["differential-gene-expression.html", "11.10 Differential gene expression", " 11.10 Differential gene expression Using this dataset, we can fit regression models to ask about differences in gene expression between conditions. For example, let’s say we’re interested in whether the ACE2 gene – the receptor bound by the SARS-CoV-2 virus – exhibits differences in expression between males and females. First we subset the data to the relevant gene and tissue (ACE2 and lung) for our test: subset <- gtex %>% # filter for tissue and gene of interest filter(Tissue == "Lung" & Gene_Name == "ACE2") head(subset) ## Sample Age Sex Death_Hardy Tissue Gene_ID Gene_Name Counts ## 1 GTEX-111YS 60-69 M 0 Lung ENSG00000130234.10 ACE2 640 ## 2 GTEX-1128S 60-69 F 2 Lung ENSG00000130234.10 ACE2 64 ## 3 GTEX-11DXX 60-69 F 0 Lung ENSG00000130234.10 ACE2 236 ## 4 GTEX-11DXZ 50-59 M 0 Lung ENSG00000130234.10 ACE2 174 ## 5 GTEX-11EMC 60-69 F 2 Lung ENSG00000130234.10 ACE2 162 ## 6 GTEX-11EQ9 30-39 M 2 Lung ENSG00000130234.10 ACE2 85 Then we can fit a model to our data. Note that we’re using the glm.nb function, which uses a negative binomial distribution – good for modeling discrete (i.e., non-continuous) data, such as sequencing read counts. # fit model and print summary model <- glm.nb(formula = Counts ~ factor(Sex), data = subset) summary(model) ## ## Call: ## glm.nb(formula = Counts ~ factor(Sex), data = subset, init.theta = 0.9820746913, ## link = log) ## ## Deviance Residuals: ## Min 1Q Median 3Q Max ## -2.0205 -0.9991 -0.5441 -0.0219 4.9984 ## ## Coefficients: ## Estimate Std. Error z value Pr(>|z|) ## (Intercept) 5.5530 0.1709 32.494 < 2e-16 *** ## factor(Sex)M -0.7907 0.2121 -3.727 0.000194 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## (Dispersion parameter for Negative Binomial(0.9821) family taken to be 1) ## ## Null deviance: 129.67 on 99 degrees of freedom ## Residual deviance: 115.01 on 98 degrees of freedom ## AIC: 1214.5 ## ## Number of Fisher Scoring iterations: 1 ## ## ## Theta: 0.982 ## Std. Err.: 0.123 ## ## 2 x log-likelihood: -1208.475 Does sex impact ACE2 expression? The p-value is significant (p = 0.000194), suggesting that sex does affect ACE2 expression. Based on the coefficient of -0.7907, it looks like males tend to have ~0.8 fewer ACE2 transcripts in lung tissue. "],["conclusion-9.html", "11.11 Conclusion", " 11.11 Conclusion In this lab, we explored the GTEx dataset to understand how genetic variation impacts gene expression. We can treat gene expression as a phenotype to search for expression and splicing QTLs, the same way we would look for variants associated with an organismal trait. Due to the multiple testing burden of testing millions of variants across thousands of genes, eQTL studies typically limit themselves to variants close to the gene body. The GTEx Portal provides a convenient interface for browsing QTL and gene expression information across tissues. "],["homework-9.html", "11.12 Homework", " 11.12 Homework 11.12.0.1 Learning Objectives Become familiar with the data available in the GTEx dataset Interpret linear models in the context of gene expression 11.12.0.2 Assignment Fit a regression model (or multiple!) to the GTEx data we downloaded in class and test for differential expression between two (or more) conditions. For example, you could look at another gene, compare between tissues, age groups, or Hardy classifications, etc. Based on the results, does the condition affect expression of your gene? Solution As an example, we’ll test for differences in ACE2 expression between liver and lung tissue. First we subset the GTEx data to just the ACE2 gene: subset <- gtex %>% # filter gene of interest filter(Gene_Name == "ACE2") head(subset) ## Sample Age Sex Death_Hardy Tissue Gene_ID Gene_Name Counts ## 1 GTEX-111YS 60-69 M 0 Lung ENSG00000130234.10 ACE2 640 ## 2 GTEX-1128S 60-69 F 2 Lung ENSG00000130234.10 ACE2 64 ## 3 GTEX-11DXX 60-69 F 0 Lung ENSG00000130234.10 ACE2 236 ## 4 GTEX-11DXZ 50-59 M 0 Liver ENSG00000130234.10 ACE2 211 ## 5 GTEX-11DXZ 50-59 M 0 Lung ENSG00000130234.10 ACE2 174 ## 6 GTEX-11EMC 60-69 F 2 Lung ENSG00000130234.10 ACE2 162 Then we fit a model with glm.nb: # fit model and print summary model <- glm.nb(formula = Counts ~ factor(Tissue), data = subset) summary(model) ## ## Call: ## glm.nb(formula = Counts ~ factor(Tissue), data = subset, init.theta = 1.034483188, ## link = log) ## ## Deviance Residuals: ## Min 1Q Median 3Q Max ## -1.9604 -0.9618 -0.4892 0.0681 6.6469 ## ## Coefficients: ## Estimate Std. Error z value Pr(>|z|) ## (Intercept) 4.6651 0.1370 34.05 < 2e-16 *** ## factor(Tissue)Lung 0.4491 0.1688 2.66 0.00781 ** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## (Dispersion parameter for Negative Binomial(1.0345) family taken to be 1) ## ## Null deviance: 180.46 on 151 degrees of freedom ## Residual deviance: 173.75 on 150 degrees of freedom ## AIC: 1819 ## ## Number of Fisher Scoring iterations: 1 ## ## ## Theta: 1.034 ## Std. Err.: 0.106 ## ## 2 x log-likelihood: -1812.977 The p-value is significant (p = 0.00781), suggesting that ACE2 expression does differ between liver and lung. The coefficient estimate, 0.4491, indicates that RNA-seq counts for ACE2 are \\(0.45\\) transcripts higher in lung than in liver. "],["coronavirus-phylogenetics.html", "12 Coronavirus phylogenetics", " 12 Coronavirus phylogenetics In this lab, we’ll use Nextstrain to explore the evolution of SARS-CoV-2 and then build our own coronavirus phylogenies within R. 12.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Interpret viral phylogenies and associated data on Nextstrain. Explain how incomplete sampling affects phylogenies. Describe how phylogenetic trees are built through neighbor joining. "],["phylogenetic-trees.html", "12.1 Phylogenetic trees", " 12.1 Phylogenetic trees Phylogenetic trees represent the evolutionary relationships between samples. When comparing genetic sequences, we construct trees based on shared mutations between sequences – with the caveat that sometimes the same mutation can arise independently on different lineages. Human vs. viral phylogenies Constructing a phylogeny for human sequences is complicated by recombination (as well as diploidy and sex chromosomes), which means that every non-recombined segment of the genome has its own phylogenetic history. Viral phylogenies are simpler to construct because they recombine less frequently than human chromosomes do. While the frequency of recombination varies by virus, ~3% of SARS-CoV-2 lineages show evidence of recombination (as opposed to 100% of human lineages, since recombination is an essential component of human meiosis). Similar to the human Y chromosome, viral genomes typically accumulate mutations without recombination to split up haplotypes. "],["nextstrain.html", "12.2 Nextstrain", " 12.2 Nextstrain We’ll be visualizing the evolutionary history of SARS-CoV-2 with a web application called Nextstrain, developed by Trevor Bedford and colleagues at the Fred Hutch Cancer Center. Reading a phylogenetic tree Nextstrain provides a guide on how to interpret their phylogenetic trees. The figure below shows a “transmission tree” of viruses, where every dot is individual who was infected. Some of these individuals infect others, and some are dead ends (no transmission). After a mutation (diamonds) occurs on a branch, any sample to the right of the mutation will also carry it. Fig. 1. The “true” tree of virus transmission through a population (source). "],["incomplete-sampling.html", "12.3 Incomplete sampling", " 12.3 Incomplete sampling The tree we just saw is the complete, “full” tree of transmission, but we are almost never able to sample all the individuals we need to reconstruct it. Incomplete sampling can result in inaccurate interpretations of a phylogenetic tree (ex: inferring fewer introductions of the virus from a source population into a new population). Fig. 2. Incomplete sampling complicates interpretations of a phylogeny (source). "],["tracking-sars-cov-2-with-phylogenetics.html", "12.4 Tracking SARS-CoV-2 with phylogenetics", " 12.4 Tracking SARS-CoV-2 with phylogenetics Go to the Nextstrain browser to explore the phylogeny of SARS-CoV-2 sequences. Note that you can use the PLAY button on the left sidebar to watch its progression over time. Hovering over a specific node tells you the ID of the virus that was sequenced. It also tells you the divergence, which is the number of mutations it carries with respect to the root of the tree. Fig. 3. SARS-CoV-2 phylogeny from Nextstrain (source). One example of the public health value of this phylogenetic analysis was the observation that the second reported case of novel coronavirus in Washington state (WA2) was genetically similar to the first reported case (WA1) six weeks earlier, suggesting ongoing community transmission. Click the tweet expand the full thread. (kevin_purcell?) Please feel free to try (click the menu Embed Tweet here) and let me know if it does not work. — Yihui Xie ((xieyihui?)) July 28, 2016 "],["sars-cov-2-mutation-landscape.html", "12.5 SARS-CoV-2 mutation landscape", " 12.5 SARS-CoV-2 mutation landscape The phylogeny page also has a “diversity” section, where it plots the number of mutations observed in different regions of the SARS-CoV-2 genome sequence. Fig. 4. Genomic distribution of mutations across SARS-CoV-2 strains (source). Does this plot imply that specific regions of the SARS-CoV-2 genome are more susceptible to mutation? No – this plot can be interpreted as showing where mutations persist in the SARS-CoV-2 genome, not where they occur. Although mutation occurrence is mostly random, the genomic distribution we see in this plot has been filtered by natural selection. Beneficial mutations are selected for, causing them to appear more frequently in pathogenically important regions like the spike protein (S). We sometimes see recurring independent mutations where the same amino acid is changed across different SARS-CoV-2 strains, which is extremely strong evidence of selection. "],["setup-8.html", "12.6 Setup", " 12.6 Setup In the rest of this module we’ll place SARS-CoV-2 on a phylogeny of 24 distantly related coronavirus sequences (SARS, MERS, etc.) from both human and animal hosts. 12.6.1 R packages We’ll use ape for phylogenetics, ggtree for plotting trees, and harrietr for data transformation. library(tidyverse) library(ape) library(ggtree) library(harrietr) "],["data-5.html", "12.7 Data", " 12.7 Data 12.7.0.1 Metadata The accessions dataframe contains the GenBank IDs and full names of the coronavirus sequences we’re using: accessions <- read.table("accessions.txt", header = TRUE, sep = "\\t") head(accessions) ## id name ## 1 DQ022305 DQ022305.2 Bat SARS coronavirus HKU3-1 ## 2 DQ071615 DQ071615.1 Bat SARS coronavirus Rp3 ## 3 DQ412043 DQ412043.1 Bat SARS coronavirus Rm1 ## 4 JX993988 JX993988.1 Bat coronavirus Cp/Yunnan2011 ## 5 FJ588686 FJ588686.1 Bat SARS CoV Rs672/2006 ## 6 JX993987 JX993987.1 Bat coronavirus Rp/Shaanxi2011 # make vectors of the GenBank IDs and full names # these will be used as input to functions later ids <- accessions$id names <- accessions$name The SARS-CoV-2 sequence we’re using is MT093631 (MT093631.2 Severe acute respiratory syndrome coronavirus 2 isolate SARS-CoV-2/human/CHN/WH-09/2020). 12.7.0.2 DNA sequences We’ve downloaded and aligned the genome sequences of these coronaviruses in the aligned.fa FASTA file. Click on the file to preview the sequence of the first coronavirus: >DQ022305 ----------------------------------------GTTAGGTTTTTACCTACCCAGGAAA--AGCCAACCAACC- TTGATCTCTTGTAGATCTGTTCTCTAAACGAACTTTAAAA------TCTGTGTGGCTGTCGCTCGGCTGCATGCCTAGCG CACCTACGCAGTATAAATATTAAT-AACTTTACTGTCGTTGACAAGAAACGAGTAACTCGTCCCTCTTCTGCAGACTGCT FASTA format .fa indicates a FASTA file, which is a text-based format for representing DNA (or protein) sequences. In a file that contains multiple sequences (like ours), the > character indicates the start of a new sequence and is usually followed by the sequence name. Why do the sequences have to be aligned? To construct a phylogeny, we compare how a site in the genome has changed in different coronavirus strains. Sequences need to be aligned so that we know we’re comparing the same site across sequences. "],["neighbor-joining-trees.html", "12.8 Neighbor joining trees", " 12.8 Neighbor joining trees One approach to building a phylogeny of sequences is neighbor joining, which clusters sequences based on their pairwise genetic distance. In this approach, we: Start with a star phylogeny that assumes all samples are equally related (Fig. 5A) Compute a pairwise distance matrix between sequences, and look for the pair of sequences that are most similar to each other We join these two sequences to form a new node (Fig. 5B) The distance matrix is re-computed and this process repeats until all nodes are joined (Fig. 5C) Fig. 5. Steps for constructing a neighbor joining tree (source). "],["computing-pairwise-distance.html", "12.9 Computing pairwise distance", " 12.9 Computing pairwise distance Read in the FASTA file of aligned sequences with the read.dna function from ape: dna <- read.dna("aligned.fa", format = "fasta", as.matrix = TRUE) We then compute the pairwise distance matrix: D <- dist.dna(dna, model = "TN93", as.matrix = TRUE) We can plot this matrix to visualize it: # use the "melt_dist" function from harrietr package to convert # the distance matrix to "long" format for ggplot D_melted <- rbind(melt_dist(D, order = ids), melt_dist(t(D), order = rev(ids))) # plot distance matrix ggplot(data = D_melted) + geom_tile(aes(x = iso1, y = iso2, fill = (dist + 1e-5))) + theme_classic() + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + scale_fill_viridis_c(name = "distance") + xlab("sample") + ylab("sample") Interpreting the distance matrix Most of these coronaviruses seem to be fairly similar – i.e., there’s no clear clustering of sequences – besides HQ166910, which looks genetically distinct from the other sequences. "],["building-a-phylogenetic-tree.html", "12.10 Building a phylogenetic tree", " 12.10 Building a phylogenetic tree Using the distance matrix, we can now: Build a neighbor joining tree using the nj() function Use HQ166910 as the outgroup to root the tree (with the root() function) Use the ladderize() function to re-orient the tree into a tidier format for plotting # build a neighbor joining tree tree <- nj(D) # manually "root" the tree by setting HQ166910 as an outgroup tree <- root(tree, which(ids == "HQ166910")) # rotate tree at nodes to make it look tidier (i.e., "ladderized") tree <- ladderize(tree) # plot the tree ggtree(tree) + theme_tree2() + geom_tiplab(label = names, size = 4) + xlim(0, 1.2) On the tree, we can see that the 2019-nCov sample (MT093631.2 Severe acute respiratory syndrome coronavirus 2) groups most closely with Bat coronavirus RaTG13. Do you think this similarity is sufficient to confirm a bat origin of SARS-CoV-2? Although the distance between SARS-CoV-2 and RaTG13 in the phylogeny looks small, it’s a large distance in phylogenetic space. Without sampling more deeply within intermediate strains between RaTG13 and SARS-CoV-2, we don’t know whether it passed through other mammalian species before being transmitted to humans. "],["assess-bootstrap-support.html", "12.11 Assess bootstrap support", " 12.11 Assess bootstrap support A useful tool for evaluating confidence in a phylogenetic tree (or any other metric) is bootstrapping. This statistical method is based on resampling data with replacement from the original dataset. In our case, we resample aligned sites (i.e., bases) from the original alignment, then build a new tree with the resampled data. By repeating this procedure many times, we can evaluate confidence in various parts of the original tree by asking how often the trees from resampled data contain these features. Run the code below to implement bootstrapping in the boot.phylo() function. The output is a vector of bootstrap support values, which we can overlay onto the tree. # set random seed set.seed(123) # bootstrap and build new trees to evaluate uncertainty myBoots <- boot.phylo(tree, dna, function(x) ladderize(root(nj(dist.dna(x, model = "TN93")), which(ids == "HQ166910"))), rooted = TRUE) ## Running bootstraps: 100 / 100 ## Calculating bootstrap values... done. # replace "NA" with zero in bootstrap results; do not label terminal nodes myBoots[is.na(myBoots)] <- 0 myBoots <- c(rep(NA, 25), myBoots) # re-plot tree with bootstrap values ggtree(tree, branch.length = "none") + theme_tree2() + geom_tiplab(label = names) + geom_label(aes(label = myBoots), size = 3) + xlim(0, 15) ## Warning: Removed 25 rows containing missing values (geom_label). "],["conclusion-10.html", "12.12 Conclusion", " 12.12 Conclusion In this module, we visualized evolutionary relationships between coronavirus strains using Nextstrain and by constructing our own phylogenies in R. We first explored Nextstrain, a browser that summarizes historical sequencing data from SARS-CoV-2 strains around the world. We observed independent recurrent mutations in pathogenically relevant regions of the SARS-CoV-2 genome, suggesting that such mutations confer a fitness benefit and are under positive selection. Using the sequences of other coronavirus strains from GenBank, we placed SARS-CoV-2 onto a neighbor joining phylogeny of closely related viruses. We used bootstrapping to provide confidence estimates for branches on our neighbor joining tree. "],["homework-10.html", "12.13 Homework", " 12.13 Homework 12.13.0.1 Learning Objectives Practice building and interpreting phylogenies in R 12.13.0.2 Assignment hw_accessions.txt and hw_aligned.fa provide the alignments and metadata for 24 human SARS-CoV-2 sequences, plus the bat RaTG13 coronavirus strain. Use this data to repeat the analysis we did in class (compute distance matrix, construct neighbor joining tree, perform bootstrapping for confidence values) to build a phylogeny of SARS-CoV-2 strains. You should use RaTG13 (accession: MN996532) as an outgroup. Solution Read in accession data: accessions <- read.table("hw_accessions.txt", sep = "\\t", header = TRUE) # make vectors of accessions IDs and full names ids <- accessions$id names <- accessions$name Construct distance matrix: # read fasta file dna <- read.dna("hw_aligned.fa", format = "fasta", as.matrix = TRUE) # compute pairwise distance matrix D <- dist.dna(dna, model = "TN93", as.matrix = TRUE) Build neighbor joining tree: # make the tree tree <- nj(D) # manually root tree at RaTG13 coronavirus tree <- root(tree, which(ids == "MN996532")) # ladderize tree tree <- ladderize(tree) Bootstrap to determine tree uncertainty: set.seed(123) myBoots <- boot.phylo(tree, dna, function(x) ladderize(root(nj(dist.dna(x, model = "TN93")), which(ids == "MN996532"))), rooted = TRUE) ## Running bootstraps: 100 / 100 ## Calculating bootstrap values... done. # replace "NA" with zero myBoots[is.na(myBoots)] <- 0 Plot the bootstrapped tree: ggtree(tree, branch.length = "none") + theme_tree2() + geom_tiplab(label = names) + geom_nodelab(label = myBoots, geom = "label", fill = "#deebf7") + xlim(0, 25) "],["authors.html", "Authors", " Authors     Credits Names Pedagogy Instructor Rajiv McCoy Content Author Stephanie Yan Content Author Kate Weaver Website Template Jeff Leek & The Johns Hopkins Data Science Lab Design Inspiration Ali Madooei & JHU Data Structures Funding JHU Center for Educational Resources Techology Fellowship Grant   ## ─ Session info ─────────────────────────────────────────────────────────────── ## setting value ## version R version 4.0.2 (2020-06-22) ## os Ubuntu 20.04.5 LTS ## system x86_64, linux-gnu ## ui X11 ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz Etc/UTC ## date 2023-07-28 ## ## ─ Packages ─────────────────────────────────────────────────────────────────── ## package * version date lib source ## admixr * 0.9.1 2020-07-03 [1] RSPM (R 4.0.2) ## ape * 5.4-1 2020-08-13 [1] RSPM (R 4.0.2) ## aplot 0.0.6 2020-09-03 [1] RSPM (R 4.0.3) ## assertthat 0.2.1 2019-03-21 [1] RSPM (R 4.0.5) ## backports 1.1.10 2020-09-15 [1] RSPM (R 4.0.2) ## BiocManager 1.30.10 2019-11-16 [1] RSPM (R 4.0.0) ## blob 1.2.1 2020-01-20 [1] RSPM (R 4.0.3) ## bookdown 0.24 2023-03-28 [1] Github (rstudio/bookdown@88bc4ea) ## broom 0.7.1 2020-10-02 [1] RSPM (R 4.0.2) ## bslib 0.4.2 2022-12-16 [1] CRAN (R 4.0.2) ## cachem 1.0.7 2023-02-24 [1] CRAN (R 4.0.2) ## calibrate 1.7.7 2020-06-19 [1] RSPM (R 4.0.1) ## callr 3.5.0 2020-10-08 [1] RSPM (R 4.0.2) ## cellranger 1.1.0 2016-07-27 [1] RSPM (R 4.0.3) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.0.2) ## cluster 2.1.0 2019-06-19 [2] CRAN (R 4.0.2) ## colorspace 1.4-1 2019-03-18 [1] RSPM (R 4.0.0) ## crayon 1.3.4 2017-09-16 [1] RSPM (R 4.0.0) ## DBI 1.1.0 2019-12-15 [1] RSPM (R 4.0.0) ## dbplyr 1.4.4 2020-05-27 [1] RSPM (R 4.0.0) ## desc 1.2.0 2018-05-01 [1] RSPM (R 4.0.3) ## devtools 2.3.2 2020-09-18 [1] RSPM (R 4.0.3) ## digest 0.6.25 2020-02-23 [1] RSPM (R 4.0.0) ## dplyr * 1.0.2 2020-08-18 [1] RSPM (R 4.0.2) ## ellipsis 0.3.1 2020-05-15 [1] RSPM (R 4.0.3) ## evaluate 0.20 2023-01-17 [1] CRAN (R 4.0.2) ## fansi 0.4.1 2020-01-08 [1] RSPM (R 4.0.0) ## farver 2.0.3 2020-01-16 [1] RSPM (R 4.0.3) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.0.2) ## forcats * 0.5.0 2020-03-01 [1] RSPM (R 4.0.0) ## fs 1.5.0 2020-07-31 [1] RSPM (R 4.0.3) ## generics 0.0.2 2018-11-29 [1] RSPM (R 4.0.0) ## ggplot2 * 3.3.2 2020-06-19 [1] RSPM (R 4.0.1) ## ggtree * 2.4.2 2021-04-26 [1] Bioconductor ## glue 1.4.2 2020-08-27 [1] RSPM (R 4.0.5) ## gtable 0.3.0 2019-03-25 [1] RSPM (R 4.0.3) ## harrietr * 0.2.3 2017-12-01 [1] RSPM (R 4.0.2) ## haven 2.3.1 2020-06-01 [1] RSPM (R 4.0.2) ## highr 0.8 2019-03-20 [1] RSPM (R 4.0.3) ## hms 0.5.3 2020-01-08 [1] RSPM (R 4.0.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.0.2) ## httr 1.4.2 2020-07-20 [1] RSPM (R 4.0.3) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.0.2) ## jsonlite 1.7.1 2020-09-07 [1] RSPM (R 4.0.2) ## knitr 1.33 2023-03-28 [1] Github (yihui/knitr@a1052d1) ## labeling 0.3 2014-08-23 [1] RSPM (R 4.0.0) ## lattice 0.20-41 2020-04-02 [2] CRAN (R 4.0.2) ## lazyeval 0.2.2 2019-03-15 [1] RSPM (R 4.0.3) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.0.2) ## lubridate 1.7.9 2020-06-08 [1] RSPM (R 4.0.2) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.0.2) ## MASS * 7.3-51.6 2020-04-26 [2] CRAN (R 4.0.2) ## Matrix 1.2-18 2019-11-27 [2] CRAN (R 4.0.2) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.0.2) ## memuse 4.1-0 2020-02-17 [1] RSPM (R 4.0.0) ## mgcv 1.8-31 2019-11-09 [2] CRAN (R 4.0.2) ## modelr 0.1.8 2020-05-19 [1] RSPM (R 4.0.3) ## munsell 0.5.0 2018-06-12 [1] RSPM (R 4.0.3) ## nlme 3.1-148 2020-05-24 [2] CRAN (R 4.0.2) ## ottrpal 1.0.1 2023-03-28 [1] Github (jhudsl/ottrpal@151e412) ## patchwork 1.0.1 2020-06-22 [1] RSPM (R 4.0.2) ## permute 0.9-5 2019-03-12 [1] RSPM (R 4.0.3) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.0.2) ## pinfsc50 1.2.0 2020-06-03 [1] RSPM (R 4.0.0) ## pkgbuild 1.1.0 2020-07-13 [1] RSPM (R 4.0.2) ## pkgconfig 2.0.3 2019-09-22 [1] RSPM (R 4.0.3) ## pkgload 1.1.0 2020-05-29 [1] RSPM (R 4.0.3) ## prettyunits 1.1.1 2020-01-24 [1] RSPM (R 4.0.3) ## processx 3.4.4 2020-09-03 [1] RSPM (R 4.0.2) ## ps 1.4.0 2020-10-07 [1] RSPM (R 4.0.2) ## purrr * 0.3.4 2020-04-17 [1] RSPM (R 4.0.5) ## qqman * 0.1.4 2017-03-16 [1] RSPM (R 4.0.0) ## R6 2.4.1 2019-11-12 [1] RSPM (R 4.0.0) ## Rcpp 1.0.10 2023-01-22 [1] CRAN (R 4.0.2) ## readr * 1.4.0 2020-10-05 [1] RSPM (R 4.0.2) ## readxl 1.3.1 2019-03-13 [1] RSPM (R 4.0.2) ## remotes 2.2.0 2020-07-21 [1] RSPM (R 4.0.3) ## reprex 0.3.0 2019-05-16 [1] RSPM (R 4.0.0) ## rlang 1.1.0 2023-03-14 [1] CRAN (R 4.0.2) ## rmarkdown 2.10 2023-03-28 [1] Github (rstudio/rmarkdown@02d3c25) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.0.2) ## rstudioapi 0.11 2020-02-07 [1] RSPM (R 4.0.0) ## rvcheck 0.1.8 2020-03-01 [1] RSPM (R 4.0.0) ## rvest 1.0.1 2023-03-28 [1] Github (tidyverse/rvest@4fe39fb) ## sass 0.4.5 2023-01-24 [1] CRAN (R 4.0.2) ## scales 1.1.1 2020-05-11 [1] RSPM (R 4.0.3) ## sessioninfo 1.1.1 2018-11-05 [1] RSPM (R 4.0.3) ## stringi 1.5.3 2020-09-09 [1] RSPM (R 4.0.3) ## stringr * 1.4.0 2019-02-10 [1] RSPM (R 4.0.3) ## testthat 3.0.1 2023-03-28 [1] Github (R-lib/testthat@e99155a) ## tibble * 3.2.1 2023-03-20 [1] CRAN (R 4.0.2) ## tidyr * 1.1.2 2020-08-27 [1] RSPM (R 4.0.2) ## tidyselect 1.1.0 2020-05-11 [1] RSPM (R 4.0.3) ## tidytree 0.3.3 2020-04-02 [1] RSPM (R 4.0.3) ## tidyverse * 1.3.0 2019-11-21 [1] RSPM (R 4.0.3) ## treeio 1.14.4 2021-04-26 [1] Bioconductor ## usethis 1.6.3 2020-09-17 [1] RSPM (R 4.0.2) ## utf8 1.1.4 2018-05-24 [1] RSPM (R 4.0.3) ## vcfR * 1.12.0 2020-09-01 [1] RSPM (R 4.0.2) ## vctrs 0.6.1 2023-03-22 [1] CRAN (R 4.0.2) ## vegan 2.5-6 2019-09-01 [1] RSPM (R 4.0.0) ## viridisLite 0.3.0 2018-02-01 [1] RSPM (R 4.0.3) ## withr 2.3.0 2020-09-22 [1] RSPM (R 4.0.2) ## xfun 0.26 2023-03-28 [1] Github (yihui/xfun@74c2a66) ## xml2 1.3.2 2020-04-23 [1] RSPM (R 4.0.3) ## yaml 2.2.1 2020-02-01 [1] RSPM (R 4.0.3) ## ## [1] /usr/local/lib/R/site-library ## [2] /usr/local/lib/R/library "],["404.html", "Page not found", " Page not found The page you requested cannot be found (perhaps it was moved or renamed). You may want to try searching to find the page's new location, or use the table of contents to find the page you are looking for. "]]
+[["index.html", "Human Genome Variation Lab 1 Homepage", " Human Genome Variation Lab 1 Homepage This is the course homepage and digital textbook for Human Genome Variation with Computational Lab (AS.020.321). 1.0.0.1 Instructor Rajiv McCoy, rajiv.mccoy[at]jhu.edu 1.0.0.2 Schedule & Logistics Session Content Session 1: The reference genome & genome browsers Session 2: De novo mutations Session 3: Linkage disequilibrium Session 4: Simulating evolution Session 5: Population structure – part I Session 6: Population structure – part II Session 7: Genome-wide association studies – part I Session 8: Genome-wide association studies – part II Session 9: Scans for selection – part I Session 10: Scans for selection – part II Session 11: Archaic admixture Session 12: Gene expression Session 13: Coronavirus phylogenetics "],["genome-browsers.html", "2 Genome browsers", " 2 Genome browsers In this module, we’ll learn how to use the UC Santa Cruz (UCSC) Genome Browser and the Integrative Genomics Viewer (IGV), two extremely popular tools for visualizing genomic data. 2.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Explain why a reference genome is an important resource for genomics research. Use the UCSC genome browser to find genomic features in a region of interest. Describe the data contained in a file of sequencing reads. Load and interpret sequencing data in IGV. "],["dna-sequencing-data.html", "2.1 DNA sequencing data", " 2.1 DNA sequencing data These days, the vast majority of genomic data is generated through high-throughput Illumina short-read sequencing. The broad steps of this sequencing process are: Extract DNA Fragment DNA Prepare for sequencer (add adapters, etc.) Amplify DNA Sequencing (add fluorescently labeled nucleotides that are read by a digital camera) Fig. 1 (source). Schematic of Illumina short-read sequencing. This sequencing approach is fast and cost efficient, but introduces two main limitations. Because of the fragmentation step, the resulting sequencing reads are extremely short (~150 bp). We don’t know where in the genome the sequencing reads came from. (This is a limitation common to nearly every sequencing experiment.) "],["assembling-a-genome.html", "2.2 Assembling a genome", " 2.2 Assembling a genome When the human genome is 3 billion base pairs long, assembling short sequencing reads into a full genome is a major computational challenge. How is genome assembly performed? We can combine sequencing reads that partially overlap with each other into longer sequences. Fig. 2. Using overlapping sequencing reads to assemble a genome. Which regions of the genome are hardest to assemble? Ideally, with enough sequencing data, we would be able to reconstruct an entire genome from overlapping reads. In practice, genome assembly is complicated by repetitive DNA – sequences in different regions of the genome that are completely or nearly identical. These repeats make it difficult (or impossible) to determine the order of the sequences around them, or how many copies of the repeat there are. Fig. 3. How repetitive sequences affect genome assembly. Resolving repetitive regions requires sequencing reads that are longer than the repeat itself, which allow us to determine the flanking sequences on the sides of the repeat. Using such long-read sequencing technology (i.e., PacBio and Nanopore sequencing), the Telomere-to-Telomere consortium was able to create a complete, ungapped assembly of the human genome in 2021. "],["the-human-reference-genome.html", "2.3 The human reference genome", " 2.3 The human reference genome Having to assemble an entire genome every time you sequence a new individual is a hassle (and often infeasible, if you don’t have enough sequencing data). Instead, we typically align sequencing reads to a reference genome – a high-quality genome assembly for that species, which we use to guide our analysis. The human reference genome was initially assembled in 2000 by the Human Genome Project, and has undergone decades of refinement since. The current version of this reference, which we’ll be using, is hg38. Whose DNA was sequenced for the human reference genome? DNA from multiple individuals was sequenced to construct the reference genome. Its sequence is a mosaic of these individuals’ DNA. You can classify the ancestry of different parts of hg38 by comparing its sequence to DNA from different populations. From this, we know that around 70% of hg38 comes from one individual, called RP11, who likely had African American ancestry. Fig. 4. Sample composition of the human reference genome. "],["ucsc-genome-browser.html", "2.4 UCSC genome browser", " 2.4 UCSC genome browser What does the human reference genome actually look like? We can view it in the UC Santa Cruz (UCSC) genome browser, an interactive website for viewing genomes – both the human reference and reference genomes for several other species. The browser also displays genome annotations, such as the locations of genes and clinically relevant genetic variants. Go to the UCSC genome browser. 2.4.1 Homepage There are a few key areas of this page: Browse/Select Species – choose the species Human Assembly – choose the version of the human reference genome Position/Search Term – type in a specific position (ex: chr2:25160915), region (ex: chr1:100000-200000), or gene name (ex: HLA-A) Fig. 5. UCSC genome browser homepage. In Position/Search Term, type in a gene you’re interested in and hit enter. Why are there different versions of the reference genome? You may have noticed that the name of the reference genome we’re using is GRCh38 or hg38, which stands for Genome Reference Consortium Human Build 38 – version 38 of the reference genome. Over time, the Genome Reference Consortium makes improvements to the reference genome by closing gaps, fixing problems, and resolving repetitive regions. hg38, the most recent version, was released in 2013. "],["viewing-one-region-of-the-genome.html", "2.5 Viewing one region of the genome", " 2.5 Viewing one region of the genome Once you hit enter, you should end up on a page like this: Fig. 6. Viewing one genomic region in the UCSC genome browser. The default display includes these broad groups of annotations: Navigation: Buttons for zooming and moving around (you can also move by clicking the display, holding, and moving your mouse); current region; search bar Position: Current position on the chromosome; current base pair position Genes: Gene annotations; gene expression by tissue; gene regulatory elements (CREs) Species comparison: DNA sequence conservation across vertebrates; regions that align with the genomes of other vertebrates Variation: Genetic variants in the dbSNP database; repeat elements Inspecting a specific track If you’re interested in more information about a specific track – for example, the POMC gene annotation – you can click on that element to go to a webpage with more details. Fig. 7. Clicking on the POMC gene track. (Note that if you click on whitespace instead of an annotation element, it will change the track’s display density instead.) Fig. 8. Clicking on whitespace to expand the RefSeq genes track. Customizing the display tracks The tracks that are automatically displayed are just a small subset of what’s available. You can select which tracks you want to see, and set their display density, by scrolling down on the page. To add a new track to your browser view, click the drop-down menu below that track and select any of the options besides hide. Here we’re viewing the “Clone Ends” track, which shows the different individuals that were sequenced to create this section of the reference genome. Fig. 9. Adding the “clone ends” track to the browser. Click the refresh button in the upper right to reload the genome view. You should see something like this, showing that this region of the reference genome was sequenced in three individuals (CH17, CTD, and RP11): Fig. 10. Viewing the “clone ends” track. "],["igv.html", "2.6 IGV", " 2.6 IGV While the UCSC genome browser lets you view the reference genome itself, we’re often interested in looking at sequencing data – sequencing reads that are aligned to the reference genome. For this we use the Integrative Genomics Viewer (IGV). Go to the IGV web app. 2.6.1 Homepage The IGV homepage is fairly empty because we haven’t loaded any sequencing reads to look at, and also because we’re zoomed too far out to see anything. The Genome tab in the upper right lets you choose which reference genome to work in. The default is hg38 A drop-down menu and search bar below the header allow you to pick a chromosome and genomic position Fig. 11. The IGV homepage. We haven’t chosen a chromosome yet, so all of them are displayed below the drop-down menu. Click on one to go to a zoomed-in view of that particular chromosome. "],["navigating-igv.html", "2.7 Navigating IGV", " 2.7 Navigating IGV Once you’ve clicked on a chromosome, zoom in until you can see colors on the top track. This track displays the DNA sequence, colored by nucleotide. The track below the DNA sequence has gene annotations from RefSeq. Fig. 12. Viewing a gene in IGV. "],["loading-sequencing-data.html", "2.8 Loading sequencing data", " 2.8 Loading sequencing data Click on the Genome drop-down menu and switch to the Human (hg38 1kg/GATK) reference genome. This version of the hg38 reference has sequencing data already loaded into the IGV web app. Once you’ve switched references, click Tracks -> 1KG Low Coverage Alignments. This gives you a list of sample to load sequencing data from. Click any sample and then OK. Fig. 13. Loading reads from a 1000 Genomes sample. "],["the-1000-genomes-project.html", "2.9 The 1000 Genomes Project", " 2.9 The 1000 Genomes Project Where did this sequencing data come from? In 2015, a study called the 1000 Genomes Project (1KG or 1KGP) sequenced 3,202 individuals from 26 globally diverse populations. Because this data is publicly available, it’s become one of the most widely used datasets in human genetics. Notably, 1KGP still excludes key regions of the world – such as Oceania, the Middle East, native American populations in North America, and many populations within Africa. Fig. 14. Regions sampled by the 1000 Genomes Project. Go to the 1000 Genomes Project website and click the Data tab. Then click the link to the data portal. Fig. 15. The data portal includes information about the samples in this dataset. Choose any individual and copy their sample ID (ex: HG00138). We can use this sample ID to find this individual’s raw sequencing data in the Sequence Read Archive (SRA). "],["sra.html", "2.10 SRA", " 2.10 SRA Search for the sample ID you chose in SRA. You should see something like this, where every item is a sequencing dataset generated for this sample. Fig. 16. Finding sequencing data in SRA. 2.10.1 Previewing sequencing data Choose any sequencing dataset, and then click on any item in the Run table at the bottom. This takes you to a page that displays a specific sequencing run (i.e., one use of a sequencing machine). Go to the Reads tab. Fig. 17. The Reads tab in SRA. The right-hand panel shows one sequencing read from this run. Note that the sequence of this read is around 100bp long – the average length for short-read Illumina sequencing. All sequencing data looks like this! It’s just a text file filled with the IDs and DNA/RNA sequences of your reads. "],["viewing-sequencing-reads-in-igv.html", "2.11 Viewing sequencing reads in IGV", " 2.11 Viewing sequencing reads in IGV Now that we’ve seen what raw sequencing data looks like, let’s look at it in IGV. Return to your IGV tab, where you should have one sample’s DNA sequencing data loaded. Make sure you’re zoomed in enough for the data to display. Fig. 18. The Reads tab in SRA. The top track is a histogram of sequencing coverage (i.e., how many reads there are at that position in the genome). The bottom track shows the reads themselves. How do we know where in the genome each read belongs? We match the sequence of the read to the sequence of the reference genome (called alignment). With 100bp reads, the probability that a match occurs by chance is \\(\\frac{1}{4^{100}}\\), or \\(6.2 * 10^{-61}\\). Extracting alignment information in IGV If you click on a specific read, IGV will display additional information about it, including: The exact position it aligns to The mapping quality (a score indicating how uniquely it aligns to this position) If you’re working with paired-end sequencing data, where its paired read is Fig. 19. Viewing additional info for one sequencing read. "],["interpreting-igv-alignments.html", "2.12 Interpreting IGV alignments", " 2.12 Interpreting IGV alignments Sequencing reads in IGV are colored at bases where they differ from the reference genome. These differences can be caused by either real genetic variation or sequencing error. How would you distinguish these two? Fig. 20. Two of these colored bases are probably real SNPs, and two are probably errors. The sequencing coverage track also colors the positions that it thinks are real variants. In the screenshot above, which spans about 2kb, there are two SNPsin the coverage track. This pattern holds more broadly through the genome – humans carry about one SNP every 1,000 bases. Is one SNP every 1,000bp a lot or a little? Humans actually have much lower amounts of genetic variation than many species, including many of the great apes. This is mostly the result of human evolutionary history. Because the effective size of human populations has historically been low, with only very recent expansion, the gene pool is still fairly homogenous, with many rare variants and few common ones. "],["conclusion.html", "2.13 Conclusion", " 2.13 Conclusion In this lab, we explored several of the most commonly used websites in genomics: 2.13.0.1 Genome browsers UCSC genome browser: Used to explore features of the human genome If you discover an interesting SNP in your research, you might look it up in the UCSC browser to see which genes it’s in/near, if it overlaps with any repetitive elements, etc. IGV: Used to visualize sequencing data It’s common practice to look at your sequencing reads in IGV to check alignment quality, verify that SNPs look like real variants and not errors, etc. 2.13.0.2 Data repositories 1000 Genomes Project: One of the largest and most diverse datasets of human sequencing data Data from 1000 Genomes is frequently used in human genetics studies SRA: A repository for publicly available sequencing data Genetics studies deposit their data in SRA if it can be made publicly available (i.e., if it has no identifiable information) "],["homework.html", "2.14 Homework", " 2.14 Homework 2.14.0.1 Assignment Create an account on Posit Cloud. "],["discovering-mutations.html", "3 Discovering mutations", " 3 Discovering mutations In this module, we’ll use DNA sequencing data from human families to explore the relationship between parental age and de novo mutations in their children. 3.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Create plots to visualize the relationship between two variables. Interpret the results of a linear model. Compare the impact of maternal vs. paternal age on de novo mutation counts. Explain what a confidence interval is and why it’s useful. "],["de-novo-mutations.html", "3.1 De novo mutations", " 3.1 De novo mutations Mutation and recombination are two biological processes that generate genetic variation. When these phenomena occur during gametogenesis, the changes that they make to DNA are passed down to the next generation through germline cells (i.e., sperm and oocyte). De novo mutations (DNMs) arise from errors in DNA replication or repair. These mutations can be single-nucleotide polymorphisms (SNPs) or insertions and deletions of DNA. Every individual typically carries around 70 de novo SNPs that were not present in either of their parents. Fig. 1. Sources of DNMs in gametogenesis. "],["recombination.html", "3.2 Recombination", " 3.2 Recombination Crossovers, or meiotic recombination, occur during prophase of meiosis I, when homologous chromosomes pair with each other. Double-strand breaks are deliberately generated in the DNA, and are then cut back and repaired based on the sequence of the homologous chromosome. These repairs can sometimes resolve in a crossover event, where sections of DNA are swapped between chromosomes. Because the sequences of homologous chromosomes differ at sites where they carry different alleles, recombination generates genetic diversity by creating new haplotypes, or combinations of alleles. Crossovers are required for meiosis in most organisms because they ensure proper homologous chromosome pairing and segregation. Humans experience 1-4 crossover events per chromosome, with longer chromosomes having more crossovers. Fig. 2. Possible outcomes for double-strand breaks generated during meiosis I. Adapted from Molecular Biology of the Cell, 6th Edition (Alberts et al.) "],["setup.html", "3.3 Setup", " 3.3 Setup In this module, we’ll use sequencing data from families to look at the relationship between DNMs, crossovers, and parental age. 3.3.1 R packages We’re using R’s tidyverse library to analyze our data. You can load this R package by running: library(tidyverse) 3.3.2 Data Our data comes from the supplementary tables of this paper by Halldorsson et al., which performed whole-genome sequencing on “trios” (two parents and one child) in Iceland. We’ve pre-processed the data to make it easier to work with. Load the pre-processed data by running the code chunk below. # read data dnm_by_age <- read.table("dnm_by_age_tidy_Halldorsson.tsv", sep = "\\t", header = TRUE) # preview data head(dnm_by_age) ## Proband_id n_paternal_dnm n_maternal_dnm n_na_dnm Father_age Mother_age ## 1 675 51 19 0 31 36 ## 2 1097 26 12 1 19 19 ## 3 1230 42 12 3 30 28 ## 4 1481 53 14 1 32 20 ## 5 1806 61 11 6 38 34 ## 6 2280 63 9 3 38 20 The columns in this table are: Proband_id: ID of the child (i.e., “proband”) n_paternal_dnm: Number of DNMs (carried by the child) that came from the father n_maternal_dnm: Number of DNMs that came from the mother n_na_dnm: Number of DNMs whose parental origin can’t be determined Father_age: Father’s age at proband’s birth Mother_age: Mother’s age at proband’s birth "],["visualizing-the-data.html", "3.4 Visualizing the data", " 3.4 Visualizing the data We can use our tidied data to ask questions about the de novo mutation rate in these Icelandic individuals. How does parental age affect the number of DNMs for males and females? Use the dnm_by_age data to plot this relationship for males. ggplot(data = dnm_by_age, # specify where ggplot should be getting the x location for each data point aes(x = Father_age, # specify where ggplot should be getting the y location for each data point y = n_paternal_dnm)) + # specify that the data should be plotted as points geom_point() Based on your plot, would you say that there’s an association between paternal age and number of DNMs? It looks like there’s a pretty strong association between paternal age and number of DNMs, where older males have more DNMs. Modify your code to plot the relationship between age and number of DNMs for females. Does there seem to be an association between maternal age and number of DNMs? ggplot(data = dnm_by_age, aes(x = Mother_age, y = n_maternal_dnm)) + geom_point() There’s also a strong positive association between maternal age and number of DNMs, although the slope (i.e., the increase in number of DNMs per year) is shallower. "],["linear-models.html", "3.5 Linear models", " 3.5 Linear models We can visually observe that age seems associated with number of DNMs in both males and females, but we need a way to ask if that this is a statistically meaningful association. We can do this with a linear model. This model fits a line to the plots that we just made, and asks if the slope is significantly different from 0 (i.e., if there’s a significant increase in DNM count as age increases). If this is a statistical test, what’s the null hypothesis? The null hypothesis for this linear model is that the slope is 0 – i.e., that there’s no association between parental age and the number of DNMs from that parent. If the slope is significantly different from 0, we can reject the null hypothesis. We’ll fit a linear model using R’s lm function. Run the following code block to open a manual describing the function. ?lm lm requires two arguments: The formula or equation it’s evaluating A table of data The formula must be in the format response variable ~ predictor variable(s), where each variable is the name of a column in our data table. Is our predictor variable the parental age or the number of DNMs? The predictor variable is parental age. We expect the number of DNMs to change as a consequence of parental age. "],["fitting-a-linear-model-for-dnms.html", "3.6 Fitting a linear model for DNMs", " 3.6 Fitting a linear model for DNMs Run the following code to fit a model for the effect of age on paternal DNMs. # fit linear model for paternal DNMs fit_pat <- lm(formula = n_paternal_dnm ~ Father_age, data = dnm_by_age) # print results of model summary(fit_pat) ## ## Call: ## lm(formula = n_paternal_dnm ~ Father_age, data = dnm_by_age) ## ## Residuals: ## Min 1Q Median 3Q Max ## -32.785 -5.683 -0.581 5.071 31.639 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 10.58819 1.70402 6.214 1.34e-09 *** ## Father_age 1.34849 0.05359 25.161 < 2e-16 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 8.426 on 388 degrees of freedom ## Multiple R-squared: 0.62, Adjusted R-squared: 0.619 ## F-statistic: 633.1 on 1 and 388 DF, p-value: < 2.2e-16 How do you interpret results from a linear model? For our purposes, the only part of the results you need to look at is the line under (Intercept) in the Coefficients section: Estimate Std. Error t value Pr(>|t|) Father_age 1.34849 0.05359 25.161 < 2e-16 *** The fourth columm, Pr(>|t|), is the p-value. Because this p-value is < 2e-16, we can reject the null hypothesis and say that there is association between paternal age and the number of paternal DNMs. The first column, Estimate, is the slope, or coefficient. Linear regression fits a line to our plot of paternal age vs. number of DNMs. The coefficient estimate is the slope of that line. The slope for paternal age given by this linear model is 1.34849. We can interpret this number this way: For every additional year of paternal age, we expect 1.35 additional paternal DNMs in the child. Modify your code to assess the relationship between maternal age and number of maternal DNMs. Is this relationship significant? How many maternal DNMs do we expect for every additional year of maternal age? # fit linear model for maternal DNMs fit_mat <- lm(formula = n_maternal_dnm ~ Mother_age, data = dnm_by_age) # print results of model summary(fit_mat) ## ## Call: ## lm(formula = n_maternal_dnm ~ Mother_age, data = dnm_by_age) ## ## Residuals: ## Min 1Q Median 3Q Max ## -9.8683 -3.1044 -0.2329 2.2394 17.5379 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 2.51442 0.98193 2.561 0.0108 * ## Mother_age 0.37846 0.03509 10.785 <2e-16 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 4.503 on 388 degrees of freedom ## Multiple R-squared: 0.2307, Adjusted R-squared: 0.2287 ## F-statistic: 116.3 on 1 and 388 DF, p-value: < 2.2e-16 The p-value is <2e-16 and the Mother_age slope is 0.37846. This relationship is significant, and we expect 0.38 more maternal DNMs for every additional year of maternal age. "],["confidence-intervals.html", "3.7 Confidence intervals", " 3.7 Confidence intervals Our models predict that there are 1.35 more DNMs for additional every year of paternal age, and 0.38 more DNMs for every additional year of maternal age. Does this mean that sperm and oocytes accumulate DNMs at different rates? The maternal and paternal slopes look different, but we need statistical evidence that they actually are. (For example, what if there’s a lot of variability in the maternal DNM data, and the true maternal coefficient could be anywhere between -1 and 10?) To do this, we compare the confidence intervals of our slope estimates. What is a confidence interval? We use confidence intervals when estimating a value – in this case, the Mother_age and Father_age slope parameters. A confidence interval (CI) is a random interval that has a 95% probability of falling on the parameter we are estimating. So, a 95% CI contains the true value of the slope 95% of the time. Keep in mind that the definition above (95% of random intervals fall on the true value) is not the same as saying there is a 95% chance that the true value falls within our interval. This latter statement is not accurate. In R, we get the confidence interval of a parameter from a linear model with the confint function. ?confint confint requires three arguments: A fitted linear model (our fit_pat variable) The parameter we want a CI for (Father_age) The CI’s probability (typically 95%) "],["calculate-95-cis.html", "3.8 Calculate 95% CIs", " 3.8 Calculate 95% CIs Run the following code to calculate the 95% confidence interval for the Father_age slope parameter. confint(fit_pat, 'Father_age', level = 0.95) ## 2.5 % 97.5 % ## Father_age 1.243118 1.45386 So, 95% of the time, the number of additional DNMs per year of paternal age is between 1.24 and 1.45. Modify your code to get the 95% CI for the Mother_age slope. What’s the interpretation of this confidence interval? confint(fit_mat, 'Mother_age', level = 0.95) ## 2.5 % 97.5 % ## Mother_age 0.3094713 0.4474528 95% of the time, the number of additional DNMs per year of maternal age is between 0.31 and 0.45. Now that we have the confidence intervals for both slope parameters, we can finally compare them. Our two CI ranges are non-overlapping. The paternal range is [1.24, 1.45] and the maternal range is [0.31, 0.45]. If the 95% CIs for two parameters don’t overlap, this strongly supports that the parameters are significantly different from one another. So, it seems likely that paternal and maternal gametes experience different rates of de novo mutation. If the CIs for two parameters overlap, are they not significantly different? Not necessarily. More analysis, like a hypothesis test, is needed to make a final decision. "],["conclusion-1.html", "3.9 Conclusion", " 3.9 Conclusion In this lab, we explored the relationship between parental age and the number of de novo mutations in their gametes. We plotted the relationship between maternal/paternal age and DNM count. This visualization suggested that DNM count increases with age for both groups. We confirmed this hypothesis by using a linear model, which tests if additional years of age have a non-zero effect on the number of DNMs. The number of paternal DNMs seemed to increase more quickly with age than maternal DNMs. We confirmed this by comparing the 95% confidence intervals of the slopes of the two models. One final question – let’s assume that there really is a difference between the effect of age on DNMs in male and female gametes. What biological reasons might be causing this difference? "],["homework-1.html", "3.10 Homework", " 3.10 Homework So far, we’ve only looked at the de novo mutation data from the Halldorsson et al. paper. Now we’ll use their data on the number of maternal and paternal origin crossovers (i.e., how many crossovers occurred across all chromosomes in the maternal and paternal gametes). 3.10.0.1 Learning Objectives Practice visualizing data with ggplot2 Interpret p-values and effect sizes from linear models "],["required-homework.html", "3.11 Required homework", " 3.11 Required homework The data from the paper has been pre-filtered for you. Run this code block to read it in: # read data crossovers <- read.table("crossovers.tsv", header = TRUE) # preview data head(crossovers) ## Proband_id n_pat_xover n_mat_xover Father_age Mother_age ## 1 3 22 51 29 28 ## 2 10 26 50 26 26 ## 3 11 25 38 25 22 ## 4 15 24 50 31 26 ## 5 20 27 35 26 24 ## 6 22 28 40 39 31 The columns in this table are: Proband_id: ID of the child n_pat_xover: Number of crossovers (carried by the child) that occurred in the paternal gametes n_mat_xover: Number of crossovers that occurred in the maternal gametes Father_age: Father’s age at proband’s birth Mother_age: Mother’s age at proband’s birth Assignment: Using the ggplot code from this module, plot the relationship between parental age and number of crossovers. As with the DNM data, make one plot for the maternal crossovers and one plot for the paternal. Do you think parental age impacts crossover number? Solution Plot paternal crossovers: ggplot(data = crossovers, # x axis is paternal age aes(x = Father_age, # y axis is number of crossovers y = n_pat_xover)) + geom_point() Plot maternal crossovers: ggplot(data = crossovers, # x axis is maternal age aes(x = Mother_age, # y axis is number of crossovers y = n_mat_xover)) + geom_point() Just by eye, it doesn’t really seem that age affects number of crossovers for either mothers or fathers. "],["optional-homework.html", "3.12 Optional homework", " 3.12 Optional homework Assignment: Fit two linear models (one paternal, one maternal) to ask if there is an association between the number of parental crossovers and parental age. If there is an association, how is the number of crossovers predicted to change with every year of maternal/paternal age? Solution # fit the model with paternal age fit_pat <- lm(data = crossovers, formula = n_pat_xover ~ Father_age) summary(fit_pat) ## ## Call: ## lm(formula = n_pat_xover ~ Father_age, data = crossovers) ## ## Residuals: ## Min 1Q Median 3Q Max ## -15.2173 -3.1880 -0.1997 2.8061 24.7652 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 26.369432 0.102736 256.67 <2e-16 *** ## Father_age -0.005852 0.003462 -1.69 0.091 . ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 4.388 on 41090 degrees of freedom ## Multiple R-squared: 6.953e-05, Adjusted R-squared: 4.519e-05 ## F-statistic: 2.857 on 1 and 41090 DF, p-value: 0.09098 There isn’t a significant association between paternal age and the number of paternal crossovers (p = 0.091). # fit the model with maternal age fit_mat <- lm(data = crossovers, formula = n_mat_xover ~ Mother_age) summary(fit_mat) ## ## Call: ## lm(formula = n_mat_xover ~ Mother_age, data = crossovers) ## ## Residuals: ## Min 1Q Median 3Q Max ## -27.161 -6.095 -0.425 5.641 45.905 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 41.709271 0.206238 202.24 <2e-16 *** ## Mother_age 0.065989 0.007576 8.71 <2e-16 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 8.685 on 41090 degrees of freedom ## Multiple R-squared: 0.001843, Adjusted R-squared: 0.001819 ## F-statistic: 75.87 on 1 and 41090 DF, p-value: < 2.2e-16 Surprisingly, there is a significant association between maternal age and the number of maternal crossovers (p < 2e-16). For every year of maternal age, we expect the child to carry 0.07 additional maternal origin crossovers. Although the maternal crossovers plot doesn’t look that impressive, our estimated slope is 0.07, which is probably too small to distinguish visually. "],["linkage-disequilibrium.html", "4 Linkage disequilibrium", " 4 Linkage disequilibrium In this module, we’ll use DNA sequencing data from human populations to assess linkage disequilibrium between two genetic variants. 4.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Define linkage disequilibrium. Manually calculate \\(D\\), \\(D'\\), and \\(r^2\\) from genotype data. Understand the differences in interpretation for different LD statistics. Explain how LD both benefits and limits genetics studies. "],["what-is-linkage-disequilibrium.html", "4.1 What is linkage disequilibrium?", " 4.1 What is linkage disequilibrium? Linkage disequlibrium (LD) refers to correlation among genotypes at multiple sites in the genome. This is a consequence of the fact that chromosomes are transmitted in “chunks” through the generations. When mutations arise, they arise on a single chromosome with a given set of alleles. The new mutation will continue to be associated with this genetic background until it is shuffled during the process of meiotic recombination. Together, a set of alleles that tend to occur together because of linkage disequilibrium is called a haplotype. Fig. 1. After a new mutation arises, recombination over the course of many generations reduces the number of variants in LD with it. "],["why-do-we-care-about-ld.html", "4.2 Why do we care about LD?", " 4.2 Why do we care about LD? As a result of linkage disequilibrium, knowledge of a genotype at one site in the genome can provide information about the genotype at another site, even if the second site was not actually genotyped. Using prior knowledge of LD to “fill in” missing genotype information is a process called imputation. Linkage disequilibrium also means that correlation between a genotype at a particular site and phenotype (e.g., disease outcome) does not imply causation. Even ignoring other possible confounders, any variant on the same haplotype could be driving the association. Beyond mutation and recombination, other evolutionary forces such as gene flow, genetic drift, and natural selection can also influence patterns of LD observed in population genetic data. Measuring linkage disequilibrium is therefore important for both medical and evolutionary studies. Fig. 2. LD can be used to impute missing genotypes, but also complicates genetic association studies (such as finding variants that cause disease). Non-causal variants in LD will perfectly co-occur with the causal variant, making it difficult to determine which one is truly causal. "],["setup-1.html", "4.3 Setup", " 4.3 Setup We’ll measure LD between two SNPs called in the 1000 Genomes Project dataset: rs28574812 (chr21:15012619) rs2251399 (chr21:15013185) We’ve preprocessed the original 1000 Genomes data such that every line in the table below represents one haplotype in the 1000 Genomes database. Load the pre-processed data by running the code below. # read data haplotypes <- read.table("snp_haplotypes.txt", header = TRUE) # preview data head(haplotypes) ## sample haplotype snp1_allele snp2_allele ## 1 HG00096 hap_1 A C ## 2 HG00096 hap_2 A C ## 3 HG00097 hap_1 A C ## 4 HG00097 hap_2 A C ## 5 HG00099 hap_1 A C ## 6 HG00099 hap_2 A C The columns in this table are: sample: Name of the individual who was sequenced haplotype: Haplotype (i.e., the maternal or paternal chromosome) that the SNP is on snp1_allele: Genotype at SNP1 on this haplotype snp2_allele: Genotype at SNP2 on this haplotype Note that there are 2,504 samples in the 1000 Genomes Project but 5,008 total lines in the table. This is because there are two lines per individual – one for each of their maternal and paternal haplotypes. Fig. 3. Our reformatted VCF shows the combinations of alleles at two SNPs of interest, for all haplotypes in the 1000 Genomes dataset. "],["are-these-snps-in-ld.html", "4.4 Are these SNPs in LD?", " 4.4 Are these SNPs in LD? If we run table on each SNP column, we can see which alleles exist at SNP1 and SNP2. SNP1 can be A or G SNP2 can be C or T table(haplotypes$snp1_allele) ## ## A G ## 3456 1552 table(haplotypes$snp2_allele) ## ## C T ## 2825 2183 If these two SNPs were in perfect LD, we’d expect to see only two haplotypes in our data (Fig. 4A). A C: If someone carries an A at SNP1, they will always carry a C at SNP2. G T: If they carry a G at SNP1, they will always carry a T at SNP2. If these two SNPs were in linkage equilibrium, the allele at SNP1 would give us no information about SNP2. We would expect to see all four possible haplotypes, in amounts proportional to the component allele frequencies (Fig. 4B). A C A T G C G T Fig. 4. When two SNPs are in perfect LD, seeing an allele on one haplotype perfectly predicts which allele is on the other haplotype. "],["counting-haplotypes-with-table.html", "4.5 Counting haplotypes with table", " 4.5 Counting haplotypes with table We can use the table function to count the occurrence of the four possible haplotypes. table(haplotypes$snp1_allele, haplotypes$snp2_allele) ## ## C T ## A 2655 801 ## G 170 1382 The table tells us that there are 2655 A C haplotypes (A at SNP1 and C at SNP2), 170 G C haplotypes, etc. Do these SNPs look like they’re in LD? It looks like there are some haplotypes (A C and G T) that are overrepresented. However, it’s hard to tell whether that’s just because an A allele at SNP1 is much more common than T is. "],["fishers-exact-test.html", "4.6 Fisher’s exact test", " 4.6 Fisher’s exact test We can wrap our table in the fisher.test function to perform a Fisher’s exact test. This test tells us whether there is a non-random association between any of the SNP alleles, while accounting for the relative proportions of each allele. fisher.test(table(haplotypes$snp1_allele, haplotypes$snp2_allele)) ## ## Fisher's Exact Test for Count Data ## ## data: table(haplotypes$snp1_allele, haplotypes$snp2_allele) ## p-value < 2.2e-16 ## alternative hypothesis: true odds ratio is not equal to 1 ## 95 percent confidence interval: ## 22.49760 32.33934 ## sample estimates: ## odds ratio ## 26.9124 The p-value is very small (< 2.2e-16), so we can reject the null hypothesis that the two SNPs are associating independently of each other. How do we interpret the odds ratio from the Fisher’s exact test? In addition to the p-value, Fisher’s Exact Test also gives us an odds ratio of 26.9, with a 95% confidence interval of [22.5, 32.3]. In this context, the odds ratio reflects how much more likely you are to see an A at SNP1 if you also see an C at SNP2. We can observe that the 95% confidence interval doesn’t overlap with 1. An odds ratio of 1 would mean that seeing C at SNP2 doesn’t influence the probability of seeing an A at SNP1. This is a somewhat non-canonical usage of Fisher’s exact test, and in our case the odds ratio applies to whatever haplotype is in the top left corner of our 4x4 table. We could rearrange the table to calculate the odds ratio for any of the three other combinations of alleles. Together, the p-value and 95% confidence interval tell us that there is strong evidence of LD between these SNPs. Perhaps this isn’t surprising, since our two SNPs are common and close to one another on chromosome 21. "],["measuring-ld-with-d.html", "4.7 Measuring LD with \\(D\\)", " 4.7 Measuring LD with \\(D\\) If SNP1 and SNP2 are in linkage equilibrium, the probability of seeing an A C haplotype should be equal to the product of the allele frequencies of A and C. This is simply the probablity of observing two events together if the events are independent. Otherwise, for SNPs that are not independent of each other, we should see A C either more or less often than expected from the allele frequencies. This intuition is summarized in \\(\\mathbf{D}\\), a population genetics statistic for measuring LD between two SNPs. \\[ D = h_{12} - p_1*p_2 \\] \\(\\mathbf{h_{12}}\\) is the frequency of our haplotype of interest (A C). \\(\\mathbf{p_1*p_2}\\) is the product of the frequencies of the two alleles on this haplotype (A at SNP1 and C at SNP2) How do we interpret \\(D\\)? If two SNPs are in linkage equilibrium, \\(h_{12}\\) and \\(p_1*p_2\\) should be the same, and we should get \\(D = 0\\). If two SNPs are in linkage disequilibrium, \\(p_1*p_2\\) should be different from \\(h_{12}\\), so that \\(D \\neq 0\\). "],["calculating-d.html", "4.8 Calculating \\(D\\)", " 4.8 Calculating \\(D\\) We can re-run our table code to find the probabilities we need for calculating \\(D\\). table(haplotypes$snp1_allele, haplotypes$snp2_allele) ## ## C T ## A 2655 801 ## G 170 1382 \\[ D = h_{12} - p_1*p_2 \\] What are \\(h_{12}\\), \\(p_1\\), and \\(p_2\\)? \\(h_{12}\\) is the probability of seeing the A C haplotype. This is equal to the number of A C haplotypes over the number of total haplotypes: \\[\\frac{2655}{2655 + 170 + 801 + 1382} = \\frac{2655}{5008}\\] \\(p_1\\) is the probability that SNP1 is A. We can get this by adding across the first row of the table (i.e., adding the number of A C and A T haplotypes): \\[\\frac{2655 + 801}{5008}\\] \\(p_2\\) is the probability that SNP2 is C. We can get this by adding across the first column of the table (i.e., adding the number of A C and G G haplotypes): \\[\\frac{2655 + 170}{5008}\\] (Note that the denominator is always 5008 – the total number of haplotypes in our dataframe.) Now we can plug in the corresponding probabilities to calculate D: # define our probabilities of interest h <- 2655 / 5008 p1 <- (2655 + 801) / 5008 p2 <- (2655 + 170) / 5008 # calculate D D <- h - (p1 * p2) D ## [1] 0.1408705 \\(D = 0.14\\), which is non-zero, suggesting that these SNPs are in LD. "],["measuring-ld-with-d-1.html", "4.9 Measuring LD with \\(D'\\)", " 4.9 Measuring LD with \\(D'\\) Aside from being nonzero, what does the value of \\(D\\) mean? This is surprisingly hard to interpret because the minimum and maximum value of \\(D\\) is different for every pair of SNPs. Why does the range of \\(D\\) change? The possible values of \\(D\\) depend on the frequencies of the alleles at each SNP. For example: If \\(p_1 = 0.5\\) and \\(p_2 = 0.5\\), then \\(D\\) is between \\([-0.25, 0.25]\\) If \\(p_1 = 0.1\\) and \\(p_2 = 0.7\\), then \\(D\\) is between \\([-0.07, 0.03]\\) The \\(\\mathbf{D'}\\) statistic fixes this issue by dividing \\(D\\) by its theoretical maximum. \\(D'\\) is constrained between \\([-1, 1]\\), where more extreme values denote stronger LD. \\[ D' = \\frac{D}{\\mathrm{max}(-p_1 p_2, -(1-p_1)(1-p_2))}, \\mathrm{\\:for\\:} D < 0 \\\\ D' = \\frac{D}{\\mathrm{min}(p_1 (1-p_2), p_2(1-p_1) )}, \\mathrm{\\:for\\:} D > 0 \\] \\(p_1\\) and \\(p_2\\) are the frequencies of the alleles at SNP1 and SNP2. Use this formula to calculate \\(D'\\) for our two SNPs of interest. Because \\(D\\) is positive, we use the second formula for \\(D'\\). First, we need to find the denominator, which is the minimum of \\(p_1 (1-p_2)\\) and \\(p_2 (1-p_1)\\). p1 * (1-p2) ## [1] 0.3008145 p2 * (1-p1) ## [1] 0.1748161 p2 * (1-p1) is smaller, so we plug that into our \\(D'\\) formula: Dprime <- D / (p2 * (1-p1)) Dprime ## [1] 0.8058206 This tells us that LD between these two SNPs is 80.6% of its theoretical maximum. "],["measuring-ld-with-r2.html", "4.10 Measuring LD with \\(r^2\\)", " 4.10 Measuring LD with \\(r^2\\) \\(\\mathbf{r^2}\\) is the most common statistic for measuring LD. Its value ranges from [0, 1], where 1 indicates maximum LD. \\[ r^2 = \\frac{D^2}{p_1 (1-p_1) p_2 (1-p_2)} \\] Although it looks similar to the formulas for \\(D\\) and \\(D'\\), \\(r^2\\) is actually derived from the correlation coefficient of the frequencies of SNP1 and SNP2, and has a slightly different interpretation: \\(D\\) and \\(D'\\) measure whether recombination has occurred between two alleles \\(r^2\\) measures how well we can predict the allele at one locus if given the allele at the other locus Calculate \\(r^2\\) for our two SNPs of interest. r2 <- D^2 / (p1*(1-p1)*p2*(1-p2)) r2 ## [1] 0.3773631 \\(r^2 = 0.38\\), indicating that these SNPs are in moderate LD. "],["ldlink.html", "4.11 LDlink", " 4.11 LDlink LDlink is a web application that allows you to compute and visualize linkage disequilibrium using data from the 1000 Genomes Project (the same dataset we’ve been using for this module). Go to LDlink’s LDpair tool, which computes \\(D'\\) and \\(r^2\\) between pairs of SNPs. Using either the rsIDs or the chromosome and position of the two SNPs we looked at today, check our calculations for \\(D'\\) and \\(r^2\\). Make sure you: Select All Populations, since we didn’t subset our data by population. If using SNP position, note that our data was aligned to the GRCh38 reference genome. Fig. 5. LDpair results for the two SNPs from this class. We can see that these \\(D'\\) and \\(r^2\\) statistics, as well as the 4x4 table, are very similar to what we calculated by hand! (The values aren’t identical because we’re using a slightly different genotyping dataset.) "],["visualizing-ld-blocks.html", "4.12 Visualizing LD blocks", " 4.12 Visualizing LD blocks LDproxy, another LDlink tool, finds all SNPs in strong LD with a SNP of interest. Open LDproxy and use it to search for one of the SNPs from today (it may take the webpage a minute to load the results). Fig. 6. LDproxy results for rs28574812. To generate this plot, LDproxy calculated \\(r^2\\) between our SNP of interest and all other SNPs in a 500kb window. As expected, we can see that LD is strongest for variants that are closest to the SNP. LDproxy also provides even more information than just LD – it also includes regulatory annotations for all the variants in this region (the numbers within each dot), as well as gene annotations and a list of nearby variants (below the plot). "],["ld-in-association-studies.html", "4.13 LD in association studies", " 4.13 LD in association studies The figure below is a locuszoom plot – a common visualization of data from genome-wide association studies (GWAS). This particular study was a GWAS for genetic variants that impact mean corpuscular hemoglobin concentration. The left y-axis is the p-value for the association with mean corpuscular hemoglobin concentration Each variant is colored by its \\(\\mathbf{r^2}\\) with the top hit variant (in purple) The heatmap on the bottom shows pairwise LD between variants The right y-axis and dark blue line show the frequency of recombination events. Peaks are recombination hotspots (note how they line up with the boundaries of LD blocks in the heatmap) We can observe a block of red/orange variants with almost the same p-value as the top hit. All of these variants are in strong LD with each other: all of them except the leftmost cluster fall within the same LD block in the heatmap on the bottom. As a result, any of them could be causal – i.e., the one that actually affects corpuscular hemoglobin. This is a problem that affects all association studies. Two common ways of working around LD to identify causal variants are: Statistical fine mapping: Uses patterns of LD and statistical models to narrow down casual variant sets Experimental screening: Tests candidate variants in vitro (ex: massively parallel reporter assays, CRISPR screens) to determine which have functional effects Fig. 7. GWAS associations with mean corpuscular hemoglobin concentration, from this paper. "],["conclusion-2.html", "4.14 Conclusion", " 4.14 Conclusion In this lab, we used genotype data from the 1000 Genomes Project to ask whether there is linkage disequilibrium between two SNPs on chr21. Using data from the VCF, we used table to count how often we observe combinations of alleles at these SNPs. We used the data in the table to calculate three LD statistics: \\(\\mathbf{D}\\): the deviation of the observed haplotype frequency from the expected haplotype frequency \\(\\mathbf{D'}\\): a normalization of \\(D\\) that ranges from \\([-1, 1]\\) \\(\\mathbf{r^2}\\): how well the allele at one locus predicts the allele at another locus We used LDlink to visualize how blocks of LD define haplotypes. "],["homework-2.html", "4.15 Homework", " 4.15 Homework 4.15.0.1 Learning Objectives Calculate and interpret LD statistics 4.15.0.2 Assignment We’ve subset the VCF from class to show haplotypes for two different pair of SNPs: chr21:15005329 and chr21:15007704 chr21:15336586 and chr21:15336794 # read data for first set of SNPs hw1 <- read.table("snp_haplotypes_hw1.txt", header = TRUE) # read data for second set of SNPs hw2 <- read.table("snp_haplotypes_hw2.txt", header = TRUE) Assignment: Using the code from class, calculate \\(D\\), \\(D'\\), and \\(r^2\\) for these sets of SNPs. Which alleles are segregating together? What does each LD statistic indicate? (Feel free to check your work on LDpair.) Solution for first set of SNPs First use table to count the occurences of the four haplotypes. table(hw1$snp1_allele, hw1$snp2_allele) ## ## A G ## C 747 2508 ## T 2 1751 All four possible haplotypes exist in this population. \\(\\mathbf{D = h_{12} - p_1*p_2}\\) h <- 747 / 5008 p1 <- (747 + 2508)/5008 p2 <- (747 + 2)/5008 D <- h - p1 * p2 D ## [1] 0.05195286 \\(D\\) is non-zero, which suggests that these SNPs might be in LD. \\(\\mathbf{D' = \\frac{D}{\\mathrm{min}(p_1 (1-p_2), p_2(1-p_1))}}\\) (because \\(D > 0\\)) First we determine the denominator by calculating which of \\(p_1 (1-p_2)\\) and \\(p_2(1-p_1)\\) is smaller: p1 * (1-p2) ## [1] 0.5527516 p2 * (1-p1) ## [1] 0.05235222 \\(p_2(1-p_1)\\) is smaller, so we use it for the denominator. \\(D'\\) is: Dprime <- D / ((1-p1) * p2) Dprime ## [1] 0.9923717 \\(D' = 0.99\\), which indicates very high LD (almost no recombination has occurred between alleles on this haplotype). \\(\\mathbf{r^2 = \\frac{D^2}{p_1 (1-p_1) q_1 (1-q_1)}}\\) r2 <- D^2 / (p1 * (1-p1) * p2 * (1-p2)) r2 ## [1] 0.09327254 However, \\(r^2 = 0.09\\) (linkage equilibrium)! This is because one of the haplotypes, A T, is very rare – there are only two copies in the population. \\(r^2\\) tells us that the counts of the A T haplotype are so low that an A at SNP1 doesn’t do a great job of predicting when SNP2 is T. Solution for second set of SNPs First use table to count the occurences of the four haplotypes. table(hw2$snp1_allele, hw2$snp2_allele) ## ## A G ## A 3522 0 ## G 0 1486 The only haplotypes that exist in this population are A C and G G. \\(\\mathbf{D = h_{12} - p_1*p_2}\\) h <- 3522 / 5008 p1 <- (3522 + 0)/5008 p2 <- (3522 + 0)/5008 D <- h - p1 * p2 D ## [1] 0.2086794 \\(D\\) is non-zero, which suggests that these SNPs might be in LD. \\(\\mathbf{D' = \\frac{D}{\\mathrm{min}(p_1 (1-q_1), (1-p_1)q_1 )}}\\) (because \\(D > 0\\)) First we determine the denominator by calculating which of \\(p_1 (1-p_1)\\) and \\(p_2 (1-p_2)\\) is smaller: p1 * (1-p2) ## [1] 0.2086794 p2 * (1-p1) ## [1] 0.2086794 The two values are exactly the same, so we can use either for the denominator. \\(D'\\) is: Dprime <- D / (p1 * (1-p2)) Dprime ## [1] 1 \\(D' = 1\\)! These SNPs are in maximum LD (no recombination has occured between them). \\(\\mathbf{r^2 = \\frac{D^2}{p_1 (1-p_1) p_2 (1-p_2)}}\\) r2 <- D^2 / (p1 * (1-p1) * p2 * (1-p2)) r2 ## [1] 1 \\(r^2 = 1\\)! These SNPs are in maximum LD (everyone who carries an A at SNP1 has an A at SNP2, and everyone with a G at SNP1 has a G at SNP2). "],["simulating-evolution.html", "5 Simulating evolution", " 5 Simulating evolution In this lab, we’ll build a simulation to explore genetic drift using the Wright-Fisher model. 5.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Describe the phenomenon of genetic drift. Explain why random draws from a binomial distribution are a good way to mimic the effect of drift. Interpret allele frequency patterns that occur as a result of drift. Write a for loop in R. Write a function to run code multiple times with different parameters. "],["genetic-drift.html", "5.1 Genetic drift", " 5.1 Genetic drift In all populations, genetic drift acts to change allele frequencies over time. Drift refers to random changes in an allele’s frequency between generations. These random changes occur because individuals carrying different alleles will have different numbers of offspring due to chance. Fig. 1 (source). An allele’s frequency “drifts” between generations due to random chance. Drift differs from selection, which is a deterministic (non-random) change in an allele’s frequency. If an allele is under selection, it’s more likely to increase or decrease in frequency depending on whether it is beneficial or deleterious. Genetic drift, on the other hand, cannot consistently cause an allele’s frequency to increase or decrease. "],["the-wright-fisher-model.html", "5.2 The Wright-Fisher model", " 5.2 The Wright-Fisher model The Wright-Fisher model is one of the most commonly used models of genetic drift. In this model, we assume that a population: Mates randomly Number of individuals remains constant between generations Today, we’ll also assume that the population is haploid Populations in the real world don’t behave like an ideal Wright-Fisher population, so their effective population size Ne is usually much smaller than their actual population size. The effective population size of the human population is only 12,800–14,400 individuals, even though its actual size is around 8 billion. "],["allele-frequency-fixation-and-loss.html", "5.3 Allele frequency, fixation, and loss", " 5.3 Allele frequency, fixation, and loss The Wright-Fisher model describes the behavior of a single allele, which can be at any variable site in a population (a SNP, insertion/deletion, version of a gene, etc.). The allele of interest begins the simulation at some initial allele frequency (AF). This allele frequency is the proportion of individuals in the population who carry that allele, and is always between 0 and 1. An allele becomes fixed in a population if it reaches an allele frequency of 1, and is lost if it reaches a frequency of 0. At either of these points, it is no longer considered a variable site because either everyone or no one in the population carries it. Fig. 2 (source). Trajectories of alleles at two loci fixing, at AF = 0 and AF = 1. "],["modeling-allele-frequencies.html", "5.4 Modeling allele frequencies", " 5.4 Modeling allele frequencies In the Wright-Fisher model, we track a population over the course of many generations. Within each generation: For every individual, we perform a coin flip to determine whether or not they have the allele. Unlike a coin, the probability of receiving an allele is equal to its allele frequency in the current generation. The more common an allele is in this generation, the more likely it is that someone in the next generation will also carry it. After flipping these coins, we know the number of people in the next generation who carry the allele. Fig. 3. Every individual flips a weighted coin to determine whether they will carry the blue allele in the next generation. The probability of carrying the allele is equal to the allele’s frequency in the current generation. "],["the-binomial-distribution.html", "5.5 The binomial distribution", " 5.5 The binomial distribution Instead of having to actually simulate all the coin flips, we can get the number of allele carriers by performing a single draw from a binomial distribution with size N (# of individual) and success probability p = AF. This distribution tells you how many successes you expect to see from a set of N independent coin flips. If we try to draw 100,000 times from a binomial distribution with population size 100 and success probability (AF) 0.5, it will look something like this: Figure 5.1: 100,000 draws from a binomial distribution. The majority of the distribution lies between 48 and 52. Just as we expect based on the allele frequency, the next generation will most likely have around 48-52 individuals with the A allele. But because this is a random draw, there’s a small chance that we might end up with many more or many fewer than that number. "],["setup-2.html", "5.6 Setup", " 5.6 Setup 5.6.1 R packages library(tidyverse) 5.6.2 Data We’ll simulate all of our own data for this lab! "],["the-rbinom-function.html", "5.7 The rbinom function", " 5.7 The rbinom function The basis of our simulation is R’s rbinom function, which allows us to sample from a binomial distribution. rbinom takes three arguments: n: how many times we’re drawing from the distribution size: the size of the population we’re sampling from (i.e. N) p: the success probability (i.e. allele frequency) Every generation, we’ll draw once to produce the number of individuals carrying the A allele in the next generation. Let’s once again look at a population of size 100, and an A allele currently at AF = 0.5. We use rbinom to get the number of individuals in the next generation who will have A: rbinom(n = 1, size = 100, prob = 0.5) ## [1] 45 Change the rbinom code so that it returns the allele frequency (instead of the number of individuals). # divide by the population size to get AF rbinom(n = 1, size = 100, prob = 0.5) / 100 ## [1] 0.51 Why do we get a different number every time we run rbinom? rbinom generates a random number between 0 and 100. Because it’s random, the number it draws will be different every time we run it. "],["increasing-population-size.html", "5.8 Increasing population size", " 5.8 Increasing population size Currently, we’re drawing from a population of 100 individuals. Now let’s see what happens when we increase the population size. (Feel free to run this code block multiple times!) rbinom(n = 1, size = 10000, prob = 0.5) / 10000 ## [1] 0.4934 If you run the code block above multiple times, you’ll observe that the AF is much closer to 0.5 than it was with a population of size 100. This lends to our intuition that an allele’s frequency fluctuates much more when a population is small, and is more stable when the population size is large. How does population size affect an allele’s time to fixation? As population size gets larger, the allele will take longer to fix. "],["simulating-multiple-generations.html", "5.9 Simulating multiple generations", " 5.9 Simulating multiple generations Currently, we draw once from a binomial distribution to get the number of individuals in one generation who carry the allele of interest. How do we adapt this to simulate multiple generations? Increasing n (ex: rbinom(n = 10, size = 100, prob = 0.5)) Increasing n only gives you multiple replicate draws from the same distribution. This doesn’t reflect multiple generations, because the allele frequency doesn’t update between generations based on the new number of alleles – it uses prob = 0.5 every time. "],["for-loops.html", "5.10 For loops", " 5.10 For loops Instead of drawing multiple times from the same distribution, we can write a for loop to repeatedly generate and update the number of individuals with the A allele. A for loop allows you to run some code X number of times. For example: for (i in 1:3) { print(i) } ## [1] 1 ## [1] 2 ## [1] 3 This for loop goes through all the values between 1 and 3, and prints each of them out. Modify the for loop to instead run our rbinom command. for (i in 1:3) { print(rbinom(n = 1, size = 100, prob = 0.5) / 100) } ## [1] 0.49 ## [1] 0.45 ## [1] 0.43 "],["updating-variables-within-a-for-loop.html", "5.11 Updating variables within a for loop", " 5.11 Updating variables within a for loop We also need to update the allele frequency in every iteration of the for loop. We do this by adding a freq variable that keeps track of the current AF: # start an initial AF of 0.5 freq <- 0.5 for (i in 1:3) { # run rbinom to generate the AF for the next generation new_freq <- rbinom(n = 1, size = 100, prob = freq) / 100 # print new AF print(new_freq) # update `freq` in each iteration of the loop freq <- new_freq } ## [1] 0.53 ## [1] 0.51 ## [1] 0.52 "],["adding-a-population-size-variable.html", "5.12 Adding a population size variable", " 5.12 Adding a population size variable Using the freq variable also gives us more flexibility than hard-coding an allele frequency into the rbinom command. Add to your code so that we also provide Ne (effective population size) as a variable (without updating it in the for loop). # set effective population size outside of for loop Ne <- 100 # start an initial AF of 0.5 freq <- 0.5 for (i in 1:3) { # run rbinom to generate the AF for the next generation new_freq <- rbinom(n = 1, size = Ne, prob = freq) / Ne # print new AF print(new_freq) # update `freq` in each iteration of the loop freq <- new_freq } ## [1] 0.53 ## [1] 0.47 ## [1] 0.43 "],["changes-in-af-over-generations.html", "5.13 Changes in AF over generations", " 5.13 Changes in AF over generations Try increasing the number of generations we run the simulation for. What patterns of change do you observe in the allele frequencies? Ne <- 100 freq <- 0.5 for (i in 1:20) { new_freq <- rbinom(n = 1, size = Ne, prob = freq) / Ne print(new_freq) freq <- new_freq } ## [1] 0.53 ## [1] 0.44 ## [1] 0.41 ## [1] 0.48 ## [1] 0.55 ## [1] 0.49 ## [1] 0.5 ## [1] 0.5 ## [1] 0.44 ## [1] 0.48 ## [1] 0.51 ## [1] 0.46 ## [1] 0.45 ## [1] 0.48 ## [1] 0.46 ## [1] 0.51 ## [1] 0.55 ## [1] 0.58 ## [1] 0.54 ## [1] 0.56 The allele frequency starts approaching either 0 or 1. "],["storing-afs-in-a-vector.html", "5.14 Storing AFs in a vector", " 5.14 Storing AFs in a vector To plot how the AF changes over time, we can store the AF at each generation in a vector. Vectors R’s version of a list, and are formed with the c() function, which stands for “combine”: my_vec <- c(0.5, 0.6) my_vec ## [1] 0.5 0.6 You can append elements to a vector called my_vec by running: my_vec <- c(my_vec, new_element). Modify the code block with our for loop to create a vector for storing allele frequencies, and then append the updated AF to it every generation. We need to create the vector before the for loop, and then append to the vector within the for loop. Ne <- 100 freq <- 0.5 # create vector to store AFs in freq_vector <- freq for (i in 1:20) { new_freq <- rbinom(n = 1, size = Ne, prob = freq) / Ne # add new freq to the AF vector freq_vector <- c(freq_vector, new_freq) freq <- new_freq } freq_vector ## [1] 0.50 0.52 0.64 0.63 0.65 0.63 0.61 0.68 0.68 0.65 0.63 0.63 0.64 0.62 0.57 ## [16] 0.60 0.61 0.63 0.64 0.65 0.68 "],["reformatting-afs-for-plotting.html", "5.15 Reformatting AFs for plotting", " 5.15 Reformatting AFs for plotting Because ggplot requires its input data to be formatted as a table, we have to convert freq_vector into some form of table (ex: a tibble or dataframe). sim_results <- tibble(af = freq_vector) head(sim_results) ## # A tibble: 6 × 1 ## af ## <dbl> ## 1 0.5 ## 2 0.52 ## 3 0.64 ## 4 0.63 ## 5 0.65 ## 6 0.63 This table contains the information that we want on the plot’s y axis. We can now add in a column containing the plot’s x axis data, which is the generation that each AF value corresponds to. sim_results <- tibble(af = freq_vector, gen = 1:21) head(sim_results) ## # A tibble: 6 × 2 ## af gen ## <dbl> <int> ## 1 0.5 1 ## 2 0.52 2 ## 3 0.64 3 ## 4 0.63 4 ## 5 0.65 5 ## 6 0.63 6 Why does the gens column range from 1 to 21 (instead of 1 to 20)? We add our starting allele frequency to freq_vector, and then simulate for 20 generations. This means that we end up with 21 AFs in our vector. "],["plotting-af-trajectory.html", "5.16 Plotting AF trajectory", " 5.16 Plotting AF trajectory Plot the trajectory of AFs over time with ggplot. ggplot(data = sim_results, aes(x = gen, y = af)) + geom_line() "],["simulating-different-parameters-with-a-function.html", "5.17 Simulating different parameters with a function", " 5.17 Simulating different parameters with a function It would be nice to be able to run our Wright-Fisher simulation with different parameters – like different starting allele frequencies, population sizes, etc. – without having to edit the for loop code every time. We can use a function to generalize the code above so we can easily re-run it. The structure of an R function You’ve already encountered many functions in R, even if you didn’t realize it at the time - rbinom, ggplot, and print are all examples of functions. An R function has four parts: <Name> <- function(<Argument(s)>) { <Body> <return()> } Name − The function is stored in your R environment as an object with this name, and you use the name to call it Argument(s) − Optional; input values that the function performs operations on Body − The code that describes what the function does Return − Optional; a return statement allows the function to return a value to the user. Without a return statement, you won’t be able to access the function’s output Here’s an example function that takes in three parameters for running rbinom, and returns the output of rbinom. binom_sim <- function(myN, mySize, myProb) { output <- rbinom(myN, mySize, myProb) return(output) } How do I know when to use a function? Functions are useful whenever you have code that you want to run multiple times with slightly different parameters. If you find yourself copying over code several times and changing just a few things, you should consider writing a function instead. "],["creating-a-wright-fisher-function.html", "5.18 Creating a Wright-Fisher function", " 5.18 Creating a Wright-Fisher function We want our function to take in parameters for the starting allele frequency, population size, and number of generations to simulate. It should return the sim_results dataframe so that we can plot the allele frequency trajectory. To write a function, we can put the code that we just wrote into the function body: run_sim <- function(Ne, freq, generations) { # note how we don't define our initial parameters for Ne, freq, etc. # because we're passing in those parameters as arguments freq_vector <- freq for (i in 1:generations) { new_freq <- rbinom(n = 1, size = Ne, prob = freq) / Ne freq_vector <- c(freq_vector, new_freq) freq <- new_freq } # convert vector of AFs into a tibble for plotting sim_results <- tibble(afs = freq_vector, gen = 1:(generations+1)) # return the tibble of AFs, so that we can access the results return(sim_results) } "],["running-a-function.html", "5.19 Running a function", " 5.19 Running a function The code block we just wrote defines the function (i.e., tells R what it should do). Now we can run the function with parameters of our choosing and plot the output: # run function results <- run_sim(Ne = 1000, freq = 0.5, generations = 10000) # plot output ggplot(data = results, aes(x = gen, y = afs)) + geom_line() Run your run_sim function a few times with different input population sizes and AFs. How does changing these inputs affect the AF trajectories that you see? # simulate a very large population results <- run_sim(Ne = 100000, freq = 0.5, generations = 1000) # plot output ggplot(data = results, aes(x = gen, y = afs)) + geom_line() # simulate a population with AF closer to 0 results <- run_sim(Ne = 1000, freq = 0.1, generations = 1000) # plot output ggplot(data = results, aes(x = gen, y = afs)) + geom_line() In general, decreasing the population size or shifting the starting AF away from 0.5 will decrease the time to fixation for an allele. "],["conclusion-3.html", "5.20 Conclusion", " 5.20 Conclusion In this lab, we built a Wright-Fisher simulation for one allele, allowing us to track how we expect its frequency to change over time under the principles of genetic drift. Within each simulated generation, we drew the number of allele carriers in the next generation from a binomial distribution. We performed these AF draws within a for loop, allowing us to update the current AF with each new generation. Finally, we wrapped our Wright-Fisher simulation code into a function, allowing us to easily re-run our simulation with different parameters for the starting AF, population size, and number of generations to simulate for. We observed that smaller population sizes and more extreme AFs (closer to 0 or 1) generally decrease an allele’s time to fixation. This simple simulation forms the core of most models used in evolutionary genetics research, which often extend this model to simulate more complex phenomena (such as different forms of selection). "],["homework-3.html", "5.21 Homework", " 5.21 Homework One way to extend our simple Wright-Fisher model is to add in selection as a parameter. Selection affects our model by altering the probability of sampling our allele of interest each generation (e.g., positive selection increases the probability, and negative selection decreases it). Previously, we assumed that this probability was equivalent to the allele’s frequency, or \\(p = \\frac{i}{N_e}\\), where \\(N_e\\) is the population size and \\(i\\) is the number of individuals who carry the allele. For the purposes of this homework, we assume that in a model with selection, this probability is instead: \\[ p = \\frac{i(1 + s)}{N_e - i + i(1+s)} \\] where \\(s\\) is the selection coefficient, and ranges from -1 to 1. What does this probability become in the absence of selection (i.e., when \\(s = 0\\))? The probability becomes \\(\\frac{i}{N_e}\\), which is the same as the allele frequency. 5.21.0.1 Learning Objectives Practice writing functions in R Interpret allele frequency trajectories under selection and drift 5.21.0.2 Assignment In the code block below, modify your run_sim function so that it takes in a selection coefficient s as a parameter. Run the simulation a few times with and without (s = 0) selection, but keeping other parameters the same (Ne = 10000, freq = 0.5, generations = 10000). What do you notice about the allele frequency trajectories? Note that most selection coefficients are thought to be extremely small – the largest known selection coefficients in humans are around 0.05. Solution # simulation function with selection run_sim_selection <- function(Ne, freq, generations, s) { freq_vector <- freq for (i in 1:generations) { # calculate p, the probability of sampling the allele, based on s i <- freq * Ne # number of individuals who currently carry the allele p <- i*(1+s) / (Ne - i + i*(1+s)) # prob is now `p`, rather than `freq` new_freq <- rbinom(n = 1, size = Ne, prob = p) / Ne freq_vector <- c(freq_vector, new_freq) freq <- new_freq } # convert vector of AFs into a tibble for plotting sim_results <- tibble(afs = freq_vector, gen = 1:(generations+1)) # return the tibble of AFs, so that we can access the results return(sim_results) } Run and plot the simulation with selection: results <- run_sim_selection(Ne = 10000, freq = 0.5, generations = 10000, s = -0.001) ggplot() + geom_line(data = results, aes(x = gen, y = afs)) + ylim(0, 1) + ylab("Allele frequency") + xlab("Generation") + ggtitle("Simulation with selection") + theme(plot.title = element_text(hjust = 0.5)) # to center the title Run and plot the simulation without selection: results <- run_sim_selection(Ne = 10000, freq = 0.5, generations = 10000, s = 0) ggplot() + geom_line(data = results, aes(x = gen, y = afs)) + ylim(0, 1) + ylab("Allele frequency") + xlab("Generation") + ggtitle("Simulation without selection") + theme(plot.title = element_text(hjust = 0.5)) # to center the title We observe that selection tends to decrease the time it takes for an allele to either fix or go extinct, because it directionally biases the probability of sampling that allele. Decreasing the absolute value of the selection coefficient will make the simulation behave more like drift. "],["population-structure.html", "6 Population structure", " 6 Population structure In this lab, we’ll perform principal component analysis (PCA) to visualize how genetic variation segregates between populations. 6.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Describe the data stored in a Variant Call Format (VCF) file. Plot and interpret an allele frequency spectrum. Perform and visualize the results of a principal component analysis. "],["what-is-a-population.html", "6.1 What is a population?", " 6.1 What is a population? In population genetics, the term population refers to a group of interbreeding individuals. Determining whether a group of individuals is a “population” is subjective. Groups exchange migrants at different rates (a process called gene flow), and there is no definitive boundary for when they constitute separate populations. "],["population-structure-1.html", "6.2 Population structure", " 6.2 Population structure Population structure is a consequence of the fact that when two groups of individuals do not freely interbreed, the two populations typically develop different patterns of genetic variation. Individuals within a population tend to be share greater genetic similarity with each other than with individuals in other populations. These differences manifest through differences in allele frequencies among populations, and result from genetic drift, natural selection, and other evolutionary forces. We can measure such allele frequency differences to reveal evolutionary relationships among populations, as well as evidence of historical natural selection. Fig. 1. Two populations polymorphic for alleles A and a. The frequency of A in Population 1 is \\(0.83\\), while its frequency in Population 2 is \\(0.15\\). "],["geography-of-genetic-variants.html", "6.3 Geography of Genetic Variants", " 6.3 Geography of Genetic Variants One quick way to visualize population structure in humans is to look at the allele frequencies of genetic variants in different regions of the world. The Geography of Genetic Variants (GGV) browser is a website that plots allele frequencies from the 1000 Genomes dataset. For a given variant, GGV plots piecharts of its frequency in the 26 populations in 1000 Genomes, superimposed over the population’s geographical location. While some variants have very similar frequencies across populations, others are much more common in specific populations – usually suggesting that these populations are more closely related to each other. Fig. 2. GGV visualization of the allele frequencies for a SNP at chr1:222087833. "],["setup-3.html", "6.4 Setup", " 6.4 Setup We’ll use the 1000 Genomes data to visualize genetic differentiation between its populations. 6.4.1 R packages library(tidyverse) "],["genotype-data.html", "6.5 Genotype data", " 6.5 Genotype data We’ve summarized genotype data from the 1000 Genomes Project into two files: all_variants.txt.gz, which contains a random selection of variants on chr21 common_variants.txt, which contains only those variants in all_variants that are common across populations # all variants all <- read.table("all_variants.txt.gz") # only common variants common <- read.table("common_variants.txt.gz") # preview first 10 columns of `all` dataframe head(all[, 1:10]) ## AF AFR_AF AMR_AF EAS_AF EUR_AF SAS_AF HG00096 HG00097 HG00099 ## chr21_10005999 0.02 0.06 0.00 0 0.00 0.00 0 0 0 ## chr21_10325486 0.02 0.00 0.01 0 0.03 0.04 0 0 0 ## chr21_10336823 0.00 0.00 0.00 0 0.00 0.00 0 0 0 ## chr21_10337236 0.00 0.00 0.00 0 0.00 0.00 0 0 0 ## chr21_10339129 0.00 0.00 0.00 0 0.00 0.00 0 0 0 ## chr21_10339141 0.00 0.00 0.00 0 0.00 0.00 0 0 0 ## HG00100 ## chr21_10005999 0 ## chr21_10325486 0 ## chr21_10336823 0 ## chr21_10337236 0 ## chr21_10339129 0 ## chr21_10339141 0 The index of the dataframe is the variant ID. * The first column (AF) contains the variant’s allele frequency (AF) dataset-wide. * The next five columns contain the variant’s AF in each of the five 1000 Genomes superpopulations. * The rest of the columns provide variant genotypes for each individual in 1000 Genomes, where: * 0 is homozygous reference * 1 is heterozygous * 2 is homozygous for variant "],["metadata.html", "6.6 Metadata", " 6.6 Metadata We’ll also read in a metadata file, which tells us which population each individual is from. metadata <- read.table("integrated_call_samples.txt", header = TRUE) head(metadata) ## sample pop superpop sex ## 1 HG00096 GBR EUR male ## 2 HG00097 GBR EUR female ## 3 HG00099 GBR EUR female ## 4 HG00100 GBR EUR female ## 5 HG00101 GBR EUR male ## 6 HG00102 GBR EUR female "],["the-allele-frequency-spectrum.html", "6.7 The allele frequency spectrum", " 6.7 The allele frequency spectrum One common visualization of genotype data is the allele frequency spectrum (AFS), which is the distribution of the allele frequencies of the variants. Plot the AFS of all variants, using the data in the AF column. ggplot(data = all, aes(x = AF)) + geom_histogram(bins = 100) Interpreting the AFS The allele frequencies in this dataset range from 0 to 1, with an exponential decay from zero, indicating that the majority of variants are rare. This is the expected shape of an AFS, since all variants arise in one individual and are unlikely to spread widely through the population just by chance. This distribution is exacerbated in human populations, where recent population expansions have resulted in an excess of rare variation. "],["theoretical-afs.html", "6.8 Theoretical AFS", " 6.8 Theoretical AFS Population geneticists have estimated that under neutral demographic expectations, each bin of the AFS should have a height that is equal to 1 over its bin number. We can use this to plot the expected AFS: # make dataframe with theoretical AFS bins # create `af_bin` column with the bin number ideal_pop <- tibble(af_bin = 1:100) %>% # create `prop` column with the expected proportion of variants mutate(., prop = 1 / af_bin) head(ideal_pop) ## # A tibble: 6 × 2 ## af_bin prop ## <int> <dbl> ## 1 1 1 ## 2 2 0.5 ## 3 3 0.333 ## 4 4 0.25 ## 5 5 0.2 ## 6 6 0.167 # plot expected AFS ggplot(ideal_pop, aes(x = af_bin, y = prop)) + geom_bar(stat = "identity") How does this compare to the AFS we see from human data? The human AFS has many more rare variants, which manifests as a higher peak on the left side of the AFS. This is due to recent population expansion in humans, which results in more human individuals and an accumulation of excess new rare variation. How would you expect the AFS to look for a contracting population (ex: endangered species)? A contracting population would result in the extinction of many alleles, resulting in more variants that drift to high frequency or go extinct. The AFS for this type of population would look more flat than the neutral expectation (fewer rare alleles, more common ones). "],["af-correlations-between-populations.html", "6.9 AF correlations between populations", " 6.9 AF correlations between populations What if we compare AFs between populations? Do we expect the same variant to have the same AFs in, for example, Africa and Europe? Plot African vs. European AF on a scatterplot. ggplot(all, aes(x = AFR_AF, y = EUR_AF)) + geom_point() Most of the variants lie near the x = y line, showing that there’s a lot of correlated AFs between African and European populations. This is due to these populations’ recent common ancestry. Outlier variants, with very different frequencies in different populations, may have reached these different AFs due to the effects of selection – which we’ll discuss in a later module. Plot AF correlations for some other population pairs. Do you notice any differences in the distributions? # east asian vs. european ggplot(all, aes(x = EAS_AF, y = EUR_AF)) + geom_point() # east asian vs. south asian ggplot(all, aes(x = EAS_AF, y = SAS_AF)) + geom_point() There’s less spread away from the y = x line for the EAS-SAS comparison. Because these populations share a common ancestor more recently than EAS-AFR, there has been less time for drift to change AFs between the populations. "],["common-variation.html", "6.10 Common variation", " 6.10 Common variation For the rest of this lab, we’ll use the common dataframe, which includes only variants where \\(0.05 < \\textrm{AF} < 0.95\\). We can look at where this set of common variants lies on the full AFS by adding vertical lines at the cutoff allele frequencies: ggplot(data = all, aes(x = AF)) + geom_histogram(bins = 100) + geom_vline(xintercept = 0.05, linetype = "dashed", color = "blue") + geom_vline(xintercept = 0.95, linetype = "dashed", color = "brown") Plot the AFS of the common dataframe, including the dashed lines we used above. ggplot(data = common, aes(x = AF)) + geom_histogram() + geom_vline(xintercept = 0.05, linetype = "dashed", color = "blue") + geom_vline(xintercept = 0.95, linetype = "dashed", color = "brown") ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. All of these variants lie within the dashed lines. Even with just common variation, we still observe an exponential decay of the allele frequencies. Also note that there are only 960 variants in the common dataframe – substantially less than the 10,000 in the all dataframe. Why only work with common variants? Rare variants are more likely to show fine-grained population structure – for example, a variant may be carried by just one individual, or just one family. Because there are so many rare variants, including them causes differences between individuals to be more pronounced than differences between populations. While this is a biologically true statement, it makes it harder to visualize population structure, which is why we subset to common variation for PCA. "],["principal-component-analysis.html", "6.11 Principal component analysis", " 6.11 Principal component analysis Principal component analysis (PCA) is a method for representing high-dimensional data (i.e., data with many variables) within a smaller number of dimensions. In our case, every individual in the VCF has genotype measurements for hundreds of variants. You can think of PCA as a projection all the individuals in our dataset into a cloud, where their position is determined by their combination of genotypes. The first principal component (PC) is the vector through the cloud of data points that captures the greatest possible variance. The second PC is the vector that captures the second greatest possible variance, and must also be perpendicular to the first vector. The same idea applies to the third, fourth, fifth, etc. PCs. Fig. 3. A PCA plot that simplifies three-dimensional data into two dimensions. For an in-depth visual walkthrough of PCA, you can go to this website. "],["reformatting-data-for-pca.html", "6.12 Reformatting data for PCA", " 6.12 Reformatting data for PCA We’re using R’s prcomp function to perform PCA on our genotype data. This function takes a matrix where the rows are the data objects (i.e., individuals) and the columns are the associated measurements (i.e., variants). First, run the code below to subset our data to just the genotypes: # subset to just genotype columns gt_matrix <- common[, 7:2510] %>% as.matrix() # view first 10 columns of matrix head(gt_matrix[, 1:10]) ## HG00096 HG00097 HG00099 HG00100 HG00101 HG00102 HG00103 HG00104 ## chr21_10467583 0 0 1 0 0 1 0 0 ## chr21_10605468 1 0 0 0 1 0 0 0 ## chr21_10616824 1 0 0 0 1 0 0 0 ## chr21_10666513 0 0 0 0 0 0 0 0 ## chr21_10700275 0 0 0 0 0 0 0 0 ## chr21_10728655 1 0 0 0 0 0 0 0 ## HG00105 HG00106 ## chr21_10467583 1 0 ## chr21_10605468 0 0 ## chr21_10616824 0 0 ## chr21_10666513 0 0 ## chr21_10700275 1 0 ## chr21_10728655 0 0 We then transpose the matrix with prcomp’s t function so that the rows are individuals and the columns are variants: # transpose (i.e., rotate) gt_matrix_T <- t(gt_matrix) # view first 10 columns of transposed matrix head(gt_matrix_T[, 1:10]) ## chr21_10467583 chr21_10605468 chr21_10616824 chr21_10666513 ## HG00096 0 1 1 0 ## HG00097 0 0 0 0 ## HG00099 1 0 0 0 ## HG00100 0 0 0 0 ## HG00101 0 1 1 0 ## HG00102 1 0 0 0 ## chr21_10700275 chr21_10728655 chr21_10732526 chr21_12976114 ## HG00096 0 1 0 0 ## HG00097 0 0 0 0 ## HG00099 0 0 0 0 ## HG00100 0 0 0 0 ## HG00101 0 0 1 0 ## HG00102 0 0 0 0 ## chr21_12977074 chr21_13065545 ## HG00096 0 0 ## HG00097 0 0 ## HG00099 0 0 ## HG00100 0 0 ## HG00101 0 0 ## HG00102 0 0 "],["performing-pca.html", "6.13 Performing PCA", " 6.13 Performing PCA We perform PCA on our genotype matrix with prcomp. pca <- prcomp(gt_matrix_T) Our output is a prcomp object. This object comprises several tables, which you can preview by typing pca$ into the console and seeing what R suggests: sdev: standard deviations of the principle components rotation, center, scale: tables we won’t use in this lab x: coordinates of the data objects (the 1000 Genomes individuals) on each PC "],["reformatting-pca-output.html", "6.14 Reformatting PCA output", " 6.14 Reformatting PCA output We can plot our PCA output using the information in pca$x. # extract `x` table x <- pca$x # preview first 10 columns head(x[, 1:10]) Every row of x is an individual, every column is a PC (going up to 960 PCs!), and the value in each cell represents the sample’s coordinate on each PC axis. Run the code below to create a dataframe of the first three PCs to plot: # create column of sample names pca_results <- data.frame(sample = rownames(x), PC1 = x[, 1], # PC1 values PC2 = x[, 2], # PC2 values PC3 = x[, 3]) # PC3 values head(pca_results) ## sample PC1 PC2 PC3 ## HG00096 HG00096 3.060014 -5.822356 -1.2683268 ## HG00097 HG00097 2.839200 -6.278675 0.8609691 ## HG00099 HG00099 1.803619 -5.171999 0.4033319 ## HG00100 HG00100 3.160473 -4.504760 1.8926507 ## HG00101 HG00101 4.035908 -4.545304 0.9407191 ## HG00102 HG00102 3.608347 -4.668695 0.7327117 "],["annotate-with-population-labels.html", "6.15 Annotate with population labels", " 6.15 Annotate with population labels Our last step is adding a column to our PCA dataframe with information about each individual’s population. To do this, we merge pca_results with our metadata table. The merge function combines two tables, merging them by matching a column of your choice (specified with by =). # merge pca_results and metadata pca_results <- merge(pca_results, metadata, # specify columns to merge on by.x = "sample", by.y = "sample") head(pca_results) ## sample PC1 PC2 PC3 pop superpop sex ## 1 HG00096 3.060014 -5.822356 -1.2683268 GBR EUR male ## 2 HG00097 2.839200 -6.278675 0.8609691 GBR EUR female ## 3 HG00099 1.803619 -5.171999 0.4033319 GBR EUR female ## 4 HG00100 3.160473 -4.504760 1.8926507 GBR EUR female ## 5 HG00101 4.035908 -4.545304 0.9407191 GBR EUR male ## 6 HG00102 3.608347 -4.668695 0.7327117 GBR EUR female "],["pca-plot.html", "6.16 PCA plot", " 6.16 PCA plot Create a scatterplot of PC1 vs. PC2, coloring by the superpop column. ggplot(data = pca_results, aes(x = PC1, y = PC2, color = superpop)) + geom_point() PC1 separates out the African populations from other populations. This is in line with our knowledge that all non-African populations descend from historical migrations out of Africa – African populations contain significant genetic diversity that is not represented outside of Africa. PC2 seems to separate the East Asian and European populations from the other three superpopulations. Repeat the plot with PC2 vs. PC3. Which superpopulations do you observe separating on PC3? ggplot(data = pca_results, aes(x = PC2, y = PC3, color = superpop)) + geom_point() PC3 separates out the Admixed American and South Asian populations, which were collapsed into one group in the first PCA plot. "],["proportion-of-variance-explained.html", "6.17 Proportion of variance explained", " 6.17 Proportion of variance explained It’s hard to tell from the PCA plot whether the separation of populations we see is meaningful, or if the plot is just exaggerating extremely minor differences between groups. We quantify this by calculating the proportion of variance explained for each PC. This tells us how much of the variation in our data is being captured by PC1, PC2, etc. Variance is the square of the standard deviation, so we can calculate proportion of variance explained from the sdev item in our pca object. Each value corresponds to the standard deviation for one PC. sd <- pca$sdev head(sd) ## [1] 5.692102 3.818282 2.122236 1.954976 1.476041 1.450018 The proportion of variance explained by a PC is its variance, divided by the sum of the variances across all PCs. Conveniently, you can calculate this for every PC at once in R: # divide variance of each PC by sum of all variances var_explained <- sd^2 / sum(sd^2) # proportion of variance explained for: var_explained[1] # PC1 ## [1] 0.09645901 var_explained[2] # PC2 ## [1] 0.04340437 var_explained[3] # PC3 ## [1] 0.01340864 So, PC1 explains only 9.65% of the variance in our data, PC2 explains 4.34%, and PC3 explains 1.34%. Add x and y axis labels to your plots with the proportion of variance explained by each PC. This is common practice for PCA. ggplot(data = pca_results, aes(x = PC1, y = PC2, color = superpop)) + geom_point() + xlab("PC1 (9.65%)") + ylab("PC2 (4.34%)") ggplot(data = pca_results, aes(x = PC2, y = PC3, color = superpop)) + geom_point() + xlab("PC2 (4.34%)") + ylab("PC3 (1.34%)") "],["conclusion-4.html", "6.18 Conclusion", " 6.18 Conclusion In this lab, we used genotype data from the 1000 Genomes Project to calculate two measures of population structure. We explored the Geography of Genetic Variants browser, a useful resource for visualizing allele frequency differences between human populations. Using genotype data from the 1000 Genomes Project, we plotted the allele frequency spectrum of variants in human populations. We saw that humans carry an excess of rare variation due to recent population expansion. Finally, we used principal component analysis to cluster individuals in our dataset by their genotype information. Plotting individuals in PCA space allowed us to distinguish the five superpopulations of 1000 Genomes. "],["homework-4.html", "6.19 Homework", " 6.19 Homework We’ll now perform PCA using all SNPs in the initial VCF – not just those that were common in 1000 Genomes individuals. In the optional homework, you’ll also use your newly generated PCA plot to predict the ancestry of an unknown sample. 6.19.0.1 Learning Objectives Perform and interpret the results of a PCA Become familiar with understanding and reusing code "],["required-homework-1.html", "6.20 Required homework", " 6.20 Required homework Assignment: Re-run the steps we used to generate our PCA plot, this time using the all dataframe. Do these plots look any different from our plots with just common variants? Solution # extract genotypes and convert to matrix gt_matrix_all <- all[, 7:2510] %>% as.matrix() # transpose gt_matrix_T_all <- t(gt_matrix_all) # perform PCA pca_all <- prcomp(gt_matrix_T_all) # extract coordinates from PCA object x_all <- pca_all$x # create dataframe for plotting pca_results_all <- data.frame(sample = rownames(x_all), PC1 = x_all[, 1], PC2 = x_all[, 2], PC3 = x_all[, 3]) # merge with metadata pca_results_all <- merge(pca_results_all, metadata, # specify columns to merge on by.x = "sample", by.y = "sample") # calculate variance explained by each PC var_explained_all <- pca_all$sdev^2 / sum(pca_all$sdev^2) # print for PC1-PC3 var_explained_all[1:3] ## [1] 0.09154081 0.03824824 0.01207284 # PC1 vs. PC2 plot ggplot(data = pca_results_all, aes(x = PC1, y = PC2, color = superpop)) + geom_point() + xlab("PC1 (9.15%)") + ylab("PC2 (3.82%)") # PC2 vs. PC3 plot ggplot(data = pca_results_all, aes(x = PC2, y = PC3, color = superpop)) + geom_point() + xlab("PC2 (3.82%)") + ylab("PC3 (1.21%)") The PCA plots actually look pretty similar to the plots with just common variants! "],["optional-homework-1.html", "6.21 Optional homework", " 6.21 Optional homework We can think of our PCA as a model of human individuals. If we have a mystery individual but we know their genotypes for the variants in our PCA, we can predict where they should lie in PCA space and thus guess their ancestry. We’ve prepared a file, unknown.txt, which contains genotypes for one mystery sample (NA21121). We’ll compare it to the PCA model that you created for the required homework. Follow the instructions to predict NA21121’s placement on your PCA plot. 6.21.0.1 Prepare unknown sample for PCA Assignment: Read in unknown.txt, convert it to a matrix, and transpose. Solution # read VCF unknown <- read.table("unknown.txt") %>% as.matrix() # transpose matrix unknown_T <- t(unknown) 6.21.0.2 Predict PCA placement of unknown sample Assignment: Run the code block below to predict and plot NA21121 on top of your PCA plot from the required homework. If necessary, plot PC2 vs. PC3 as well. What superpopulation do you think NA21121 is from? Solution # predict pca placement of unknown data unknown_pca <- predict(pca_all, unknown_T) # create dataframe from predicted PCA unknown_results <- data.frame("PC1" = unknown_pca[, "PC1"], "PC2" = unknown_pca[, "PC2"], "PC3" = unknown_pca[, "PC3"], "sample" = "NA21121") # plot PC1 vs. PC2 and then predicted sample ggplot() + # PCA plot from required homework geom_point(data = pca_results_all, aes(x = PC1, y = PC2, color = superpop)) + # plots the unknown sample's location on the PCs geom_label(data = unknown_results, aes(x = PC1, y = PC2, label = sample)) + xlab("PC1 (9.15%)") + ylab("PC2 (3.82%)") # plot PC2 vs. PC3 ggplot() + geom_point(data = pca_results_all, aes(x = PC2, y = PC3, color = superpop)) + geom_label(data = unknown_results, aes(x = PC2, y = PC3, label = sample)) + xlab("PC2 (3.82%)") + ylab("PC3 (1.21%)") NA21121 seems to be part of the SAS (South Asian) superpopulation. If we look up the sample ID in the 1000 Genomes database, we can confirm that it’s part of the Gujarati Indians in Houston, TX. "],["genome-wide-association-studies-i.html", "7 Genome-wide association studies I", " 7 Genome-wide association studies I In this lab, we’ll introduce and discuss the limitations of genome-wide association studies (GWAS). 7.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Explain the statistical method that underlies GWAS. Describe the statistical challenges of GWAS. Understand how linkage disequilibrium helps and hinders GWAS. Interpret common GWAS plots and summary statistics. "],["association-studies.html", "7.1 Association studies", " 7.1 Association studies One of the central goals of human genetics is understanding the relationship between genotype and phenotype. Genome-wide association studies (GWAS) emerged ~20 years ago as a useful approach for discovering genetic variation that underlies variation in human traits. To conduct GWAS, you: Go through every variant in the genome Ask if its allele frequency differs between individuals who have or don’t have a phenotype of interest For most variants (Fig. 1, SNP 1), there will be very little difference Identify the variants with the largest association between genotype and phenotype (Fig. 1, SNP 2) Fig. 1. In this GWAS cohort, SNP 2 is significantly associated with the phenotype. The phenotype can be any measurable trait, whether it’s binary (ex: if someone has a disease) or continuous (ex: height). "],["gwas-is-just-linear-regression.html", "7.2 GWAS is just linear regression", " 7.2 GWAS is just linear regression At their core, GWAS involve fitting linear models to test for relationships between variants and phenotypes using data from large samples of individuals. As with the linear models we covered in the DNM module, GWAS fits a line to a set of points. In this case, each point is one individual in the dataset, stratified by their genotype for a variant of interest. Fig. 2 (source). GWAS fits a linear model for every variant, where the x axis is genotype and the y axis is a phenotype. Because there are so many variants in the genome and we perform a separate statistical test for each one, we often end up fitting millions of linear models for a GWAS. "],["multiple-testing.html", "7.3 Multiple testing", " 7.3 Multiple testing What are statistical challenges of performing a test multiple times? When we perform any test multiple times, we increase the risk that a “significant” result is only significant by chance. Under the null hypothesis, we assume that p-values follow a uniform distribution (i.e., a flat distribution from 0 to 1). We can plot this null distribution in R: # generate 1,000,000 "p-values" from a uniform distribution pvalues <- runif(1000000) # histogram with R's base plotting function hist(pvalues) If we use the typical p-value threshold of \\(0.05\\), 5% of our tests will have \\(p < 0.05\\), even though these p-values were simulated from a null distribution (i.e., no real association). How do we correct for multiple testing? One common multiple testing correction method, Bonferroni correction, sets a stricter p-value threshold. With Bonferroni, you divide your desired p-value by the number of independent tests you conducted. Are GWAS tests (variants) statistically independent? How does this affect our p-value threshold? As we learned in the LD module, the genotypes of nearby variants are correlated. This non-independence means that we can be less strict with multiple testing correction, because we aren’t performing as many independent tests as we think we are. Researchers have calculated that \\(\\mathbf{5*10^{-8}}\\) is an appropriate p-value threshold for GWAS in humans, given the amount of LD in human genomes. "],["ld-and-gwas.html", "7.4 LD and GWAS", " 7.4 LD and GWAS LD is both a blessing and a curse for GWAS. On one hand, LD means that we need not genotype every SNP to discover associations. We merely need to genotype “tag SNPs”, which are in LD with variants that causally influence the phenotype. On the other hand, this also means that even when we find a signficant association, it is often challenging to disentangle the causal gene and/or variant that drives the association from all the other variants on the same haplotype. Fig. 3 (source). Even without finding the causal variant, we can still discover the causal haplotype through genotyping variants in LD . "],["imputation.html", "7.5 Imputation", " 7.5 Imputation LD also means that we can perform imputation to improve our GWAS discovery power. If we know which variants tend to occur together on the same haplotype, we can infer the presence of variants in an individual even if those SNPs were never sequenced. In imputation, you: Genotype individuals using the sequencing data you have (Fig. 4A) Use a reference panel of haplotypes to fill in variants you didn’t genotype (Fig. 4B) Perform GWAS Imputation can discover GWAS signals that were hidden in the original variant set (Fig. 4B vs. Fig. 4F), or further support signals you already found. Fig. 4 (source). Imputing variants that were not actually sequenced. "],["qq-plots.html", "7.6 QQ plots", " 7.6 QQ plots One common visualization for GWAS results is a QQ plot, which compares the distribution of p-values in our results to a null distribution (i.e., the uniform distribution that we plotted earlier). How do you make a QQ plot? Generate simulated p-values from a uniform distribution – the number of simulated p-values should equal the number of actual p-values Sort both your real and simulated p-values in descending order Plot the first, second, third, etc. p-values, where x-axis is the simulated value y-axis is the actual value Fig. 5 (source). QQ plots visualize the distriution of p-values compared to a null distribution. There are three areas of this plot where points can fall: On the \\(\\mathbf{x = y}\\) line: No association signal Above the \\(\\mathbf{x = y}\\) line: Some association signal Below the \\(\\mathbf{x = y}\\) line: Issue with our statistical test (ex: not appropriately adjusting for covariates) "],["manhattan-plots.html", "7.7 Manhattan plots", " 7.7 Manhattan plots Manhattan plots show the distribution of GWAS hits across the genome, where the y-axis is p-value. </br. Fig. 6. Manhattan plot of GWAS results. The red line is the \\(5*10^{-8}\\) genome-wide significance threshold. Why are there peaks in the Manhattan plot? Each peak is composed of variants from the same haplotype, which all have a strong association with the phenotype because of LD. "],["sample-size.html", "7.8 Sample size", " 7.8 Sample size As GWAS sample size has increased over the years, each larger study is able to discover more variants. Fig. 7 (source). Increase in GWAS discovery power with sample size. Why do we find more associations with larger studies? A larger dataset captures more rare variation A larger dataset provides more statistical power – we can more confidently say whether allele frequencies are different between individuals with and without a phenotype "],["interpreting-gwas-results.html", "7.9 Interpreting GWAS results", " 7.9 Interpreting GWAS results Let’s look at a browser of GWAS results, generated by a study that used genotype and phenotype data from the UK Biobank. UK Biobank UK Biobank is one of the largest cohorts of genotype and phenotype data available. This study has data from ~500,000 individuals across the UK, including health records and responses to surveys, all of which are publicly available for research. As an example, let’s look up associations with standing height. Fig. 8. GWAS results for standing height. For each phenotype, the browser shows a Manhattan plot of associated variants The top p-values for this trait look extremely significant Bottom of the page also has a QQ plot Although these p-values are huge, keep in mind that for the vast majority of extremely strong associations, the total proportion of variance explained is very small (< 10%). (i.e., most of the natural variation in the phenotype is not explained by that variant.) "],["conclusion-5.html", "7.10 Conclusion", " 7.10 Conclusion In this lab, we gave a conceptual overview of genome-wide association studies. GWAS are an attempt to answer one of the oldest questions in genetics: How does genotype impact phenotype? In GWAS, you go through every variant in the genome and fit a linear model to ask if genotype at that variant is associated with a phenotype of interest. Multiple testing correction accounts for the statistical burden of these tests. Linkage disequilibrium helps us discover more GWAS hits, but also limits our ability to identify causal variants/genes. QQ plots and Manhattan plots are common visualizations of GWAS results. "],["homework-5.html", "7.11 Homework", " 7.11 Homework 7.11.0.1 Learning Objectives Interpret the summary statistics typically reported in GWAS studies Understand the limitations and biases of GWAS 7.11.0.2 Assignment Find any GWAS paper. Read it and report: Phenotype being studied Sample size Population being studied (homogeneous? Multi-ethnic? If it’s multi-ethnic, how do they correct for the effect of ancestry?) For the top asssociation: p-value (would you call it significant genome wide?) Effect size Did the authors replicate the result in an independent cohort? Haplotype structure, nearby genes, causal variant Example solution Example GWAS: Genome-wide analysis identifies genetic effects on reproductive success and ongoing natural selection at the FADS locus. Phenotype: Number of children ever born Sample size:: 785,604 Population: European; no population structure correction (but did control for family structure) Top asssociation: rs201815280, chr3:85546181, A->ACACC (from Supp. Table 7) p-value: 5.25e-26, seems genome-wide significant Effect size: 0.0249 (with every copy of the ACACC allele, individuals have one more child born) Replication: Did not replicate in a cohort of 34,367 women from the FinnGen study (p = 0.177) Haplotype structure, nearby genes, causal variant: In an intron of CADM2; no causal variant or LD analysis "],["genome-wide-association-studies-ii.html", "8 Genome-wide association studies II", " 8 Genome-wide association studies II In this lab, we’ll perform a GWAS. The data and exercises for this module were adapted from a GWAS workshop created by Heather Wheeler from Loyola University Chicago. 8.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Perform GWAS of a single SNP using linear regression. Use PLINK to perform GWAS on all SNPs in a VCF. Create and interpret common GWAS visualization plots. "],["setup-4.html", "8.1 Setup", " 8.1 Setup The premise for this exercise is that you’re part of a company developing a cancer drug called . Today, we’ll perform a GWAS on resistance to two drugs (GS451 and CB1908) in 1000 Genomes lymphblastoid cell lines. The phenotype we’re interested in is \\(\\mathbf{IC_{50}}\\), defined as the concentration of the drug at which the cells experience 50% viability. 8.1.1 R packages In addition to tidyverse, we’ll use vcfR to read in genotype data and qqman to create Manhattan and QQ plots. library(tidyverse) library(vcfR) library(qqman) "],["data-2.html", "8.2 Data", " 8.2 Data GWAS requires information on both genotype and phenotype in the same individuals. The genotype data we’re using are real data from the Yoruba population in the 1000 Genomes Project, but the phenotype data is simulated. Why can’t we use real phenotype data? The combination of genotype and phenotype data poses a privacy risk, so real genotype and phenotype data are often stored in controlled-access databases such as dbGaP. Although these data are still available to researchers who want to work with it, access usually requires submitting an application to explain what your intend to do with it. "],["variant-call-format-vcf.html", "8.3 Variant Call Format (VCF)", " 8.3 Variant Call Format (VCF) Our genotype data is stored in a Variant Call Format (VCF) file. VCF files contain genotype data for variants of interest in a genome. Click on genotypes_subset.vcf in the Posit Files pane to view it. This file is a subset of a much larger VCF that we’ll use later to run a genome-wide GWAS. "],["vcf-header.html", "8.4 VCF header", " 8.4 VCF header The first section of a VCF is a multi-line header – marked by the ## character – which contains metadata and descriptions of some of the columns (like INFO and FORMAT). ##fileformat=VCFv4.2 ##fileDate=20200327 ##source=PLINKv1.90 ##contig=<ID=1,length=247169191> ##contig=<ID=2,length=242739671> ##contig=<ID=3,length=199318156> ##contig=<ID=4,length=191166588> ##contig=<ID=5,length=180617248> ##contig=<ID=6,length=170727838> ##contig=<ID=7,length=158798775> ##contig=<ID=8,length=146266471> ##contig=<ID=9,length=140174583> ##contig=<ID=10,length=135279752> ##contig=<ID=11,length=134426071> ##contig=<ID=12,length=132256834> ##contig=<ID=13,length=114114508> ##contig=<ID=14,length=106354055> ##contig=<ID=15,length=100209453> ##contig=<ID=16,length=88670345> ##contig=<ID=17,length=78634628> ##contig=<ID=18,length=76098044> ##contig=<ID=19,length=63771070> ##contig=<ID=20,length=62382908> ##contig=<ID=21,length=46924584> ##contig=<ID=22,length=49503800> ##INFO=<ID=PR,Number=0,Type=Flag,Description="Provisional reference allele, may not be based on real reference genome"> ##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype"> The final line of the header (marked with just one #) gives the names of the data columns. Note that there are over a hundred columns because each individual (1001, 1002, etc.) has their own column. #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 "],["vcf-data.html", "8.5 VCF data", " 8.5 VCF data The data section of a VCF describes genetic variants. The first 9 columns give information about the variant itself – its position, the reference/alternative alleles, etc. The rest of the columns are sample-specific, and contain the individual’s genotype at that variant. 1 558185 rs9699599 A G . . PR GT 0/0 0/0 0/0 0/1 0/0 0/1 ./. 0/0 0/0 0/0 0/1 0/0 0/0 0/0 0/0 0/1 0/0 0/1 0/0 0/0 0/0 0/0 0/0 0/0 0/0 ./. 0/0 0/0 0/0 0/0 0/1 0/0 0/1 0/1 0/0 0/1 ./. 0/1 0/1 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/1 0/0 0/1 0/0 0/0 0/0 0/1 0/0 0/1 0/0 0/0 0/0 ./. 0/0 0/0 0/0 0/1 0/0 0/1 0/0 0/1 0/0 0/1 0/0 0/0 0/1 0/0 ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. ./. How do you interpret VCF genotypes? 0/0: homozygous reference (does not carry the variant) 0/1 or 1|0: heterozygous 1/1: homozygous alternate (both chromosomes have the variant) ./.: Missing genotype (could not be confidently called) The sample-specific columns often include additional genotype information, like the number of sequencing reads from the individual that support the reference vs. alternative alleles. The included fields are specified column 9 (FORMAT) (which in this case just reads GT, for “genotype”). "],["reading-in-genotype-data.html", "8.6 Reading in genotype data", " 8.6 Reading in genotype data Because VCF format can be hard to work with, we’ll use the vcfR package to manipulate our genotype data. # load the VCF with vcfR vcf <- read.vcfR("genotypes_subset.vcf") ## Scanning file to determine attributes. ## File attributes: ## meta lines: 27 ## header_line: 28 ## variant count: 72 ## column count: 185 ## Meta line 27 read in. ## All meta lines processed. ## gt matrix initialized. ## Character matrix gt created. ## Character matrix gt rows: 72 ## Character matrix gt cols: 185 ## skip: 0 ## nrows: 72 ## row_num: 0 ## Processed variant: 72 ## All variants processed "],["tidying-vcf.html", "8.7 Tidying VCF", " 8.7 Tidying VCF We’ll first work with just the first SNP in the dataset, using the vcfR2tidy function to isolate the SNP of interest and extract its genotypes. # extract first SNP, convert to tidy df, and get genotypes test_snp_gt <- vcfR2tidy(vcf[1, ])$gt ## Extracting gt element GT head(test_snp_gt) ## # A tibble: 6 × 5 ## ChromKey POS Indiv gt_GT gt_GT_alleles ## <int> <int> <chr> <chr> <chr> ## 1 1 558185 1001 0/0 A/A ## 2 1 558185 1002 0/0 A/A ## 3 1 558185 1003 0/0 A/A ## 4 1 558185 1004 0/1 A/G ## 5 1 558185 1005 0/0 A/A ## 6 1 558185 1006 0/1 A/G Every row in the test_snp_gt dataframe is a different individual in the VCF. "],["counting-allele-dosage.html", "8.8 Counting allele dosage", " 8.8 Counting allele dosage We’re often interested in encoding genotypes as a 0, 1, or 2, which you can think of as the dosage of the minor allele. This is an additive model, and assumes that the phenotype of the heterozygote is intermediate between those of the two homozygotes. We can use the table function on the gt_GT_alleles column to quickly check how many individuals have each genotype. # tabulate genotype counts table(test_snp_gt$gt_GT_alleles) ## ## A/A A/G ## 66 20 Now we’ll use the mutate function to create a new column of the dataframe that counts the dosage of the minor allele (i.e., how many G’s each person has at that SNP): # convert genotypes to counts (i.e., dosage) of minor allele test_snp_gt <- test_snp_gt %>% # count number of Gs mutate(dosage = str_count(gt_GT_alleles, "G")) %>% drop_na() head(test_snp_gt) ## # A tibble: 6 × 6 ## ChromKey POS Indiv gt_GT gt_GT_alleles dosage ## <int> <int> <chr> <chr> <chr> <int> ## 1 1 558185 1001 0/0 A/A 0 ## 2 1 558185 1002 0/0 A/A 0 ## 3 1 558185 1003 0/0 A/A 0 ## 4 1 558185 1004 0/1 A/G 1 ## 5 1 558185 1005 0/0 A/A 0 ## 6 1 558185 1006 0/1 A/G 1 Checking our work with table If we run table on the dosage column, we should get the same breakdown of genotypes as we got from the gt_GT_alleles columns. # make sure we get the same genotype counts table(test_snp_gt$dosage) ## ## 0 1 ## 66 20 "],["phenotype-data.html", "8.9 Phenotype data", " 8.9 Phenotype data Our phenotype for this GWAS is the \\(\\mathbf{IC_{50}}\\) – the concentration of the GS451 drug that at which we observe 50% viability in cell culture. # read in phenotypes phenotypes <- read.table("GS451_IC50.txt", header = TRUE) head(phenotypes) ## FID IID GS451_IC50 ## 1 1001 1001 5.594256 ## 2 1002 1002 8.525633 ## 3 1003 1003 12.736739 ## 4 1004 1004 12.175201 ## 5 1005 1005 9.936742 ## 6 1006 1006 9.163483 The columns of this table are: FID & IID: Family and individual IDs of the individual GS451_IC50: Measured \\(\\mathrm{IC_{50}}\\) for the drug of interest Plot the distribution of the phenotype. ggplot(data = phenotypes, aes(x = GS451_IC50)) + geom_histogram() ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. ## Warning: Removed 1 rows containing non-finite values (stat_bin). This data looks approximately normally distributed. This is important to check because this is one of the assumptions of linear regression, which we’ll be using to perform the GWAS. "],["merging-genotype-and-phenotype-data.html", "8.10 Merging genotype and phenotype data", " 8.10 Merging genotype and phenotype data To perform a GWAS, we need to combine genotype and phenotype information for the same individuals. This means merging these two data for our SNP of interest, which we do with the merge function: # merge genotype and phenotype info for test SNP gwas_data <- merge(test_snp_gt, phenotypes, by.x = "Indiv", by.y = "IID") head(gwas_data) ## Indiv ChromKey POS gt_GT gt_GT_alleles dosage FID GS451_IC50 ## 1 1001 1 558185 0/0 A/A 0 1001 5.594256 ## 2 1002 1 558185 0/0 A/A 0 1002 8.525633 ## 3 1003 1 558185 0/0 A/A 0 1003 12.736739 ## 4 1004 1 558185 0/1 A/G 1 1004 12.175201 ## 5 1005 1 558185 0/0 A/A 0 1005 9.936742 ## 6 1006 1 558185 0/1 A/G 1 1006 9.163483 "],["gwas-for-one-variant.html", "8.11 GWAS for one variant", " 8.11 GWAS for one variant Under the hood, GWAS is just linear regression – simple statistical models to assess evidence of a relationship between two variables. We can perform this linear regression by hand, using data from the first SNP in the VCF. In our model, we’ll be asking whether there’s a relationship between an individual’s genotype (their dosage of the SNP) and phenotype (their \\(\\mathrm{IC_{50}}\\) for GS451). Why did we merge our genotype and phenotype data? When we fit linear models in the DNM module, we needed our variables (age and # of DNMs) to be separate columns of the same table. Similarly, now that our variables are genotype and phenotype, they need to be in the same dataframe. "],["genotype-phenotype-boxplots.html", "8.12 Genotype-phenotype boxplots", " 8.12 Genotype-phenotype boxplots First, let’s plot the relationship between genotype and phenotype to see if it looks interesting. Create boxplots of the phenotype, stratified by genotype of the test SNP. ggplot(data = gwas_data) + geom_boxplot(aes(x = gt_GT_alleles, y = GS451_IC50)) ## Warning: Removed 1 rows containing non-finite values (stat_boxplot). It’s unclear whether there’s a relationship here, because the phenotype distributions for these two genotypes are mostly overlapping. To be certain, we’ll now test this with linear regression. "],["linear-regression.html", "8.13 Linear regression", " 8.13 Linear regression The function to perform linear regression in R is lm(). It takes as arguments a data frame (gwas_data) and a model formula of the form outcome ~ predictors. In the case of GWAS, our outcome is the phenotype, and our predictor is the SNP genotype. We may also include covariates such as sex, age, or ancestry as additional predictors (called covariates) to control for their potential confounding effects. No such data are available here, so we just run the simple genotype vs. phenotype test. # test for association between genotype and phenotype lm(data = gwas_data, formula = GS451_IC50 ~ dosage) %>% # directly pipe (%>%) model results to the `summary()` function summary() ## ## Call: ## lm(formula = GS451_IC50 ~ dosage, data = gwas_data) ## ## Residuals: ## Min 1Q Median 3Q Max ## -5.0247 -1.9643 -0.3867 2.1967 6.6201 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 6.5712 0.3299 19.921 <2e-16 *** ## dosage 1.3846 0.6800 2.036 0.0449 * ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 2.659 on 83 degrees of freedom ## (1 observation deleted due to missingness) ## Multiple R-squared: 0.04757, Adjusted R-squared: 0.0361 ## F-statistic: 4.146 on 1 and 83 DF, p-value: 0.04493 How do we interpret the results of the linear model? The coefficient for dosage indicates that on average, each copy of the “G” allele increases \\(\\mathrm{IC_{50}}\\) by \\(1.38\\). The p-value indicates that this slope of \\(1.38\\) is significantly greater than 0 (\\(p = 0.0449\\)). Do you think this SNP would reach genome-wide significance? This p-value is borderline, sitting very close to the arbitrary cutoff of \\(0.05\\) which is generally used to determine statistical significance. If this was the only SNP that we were investigating, we might find this result promising. However, this SNP is just one of hundreds of thousands of SNPs that we will test for association, so the burden of proof will need to be much higher. Recall that the genome-wide significance threshold for GWAS in humans is \\(5 * 10^{-8}\\). "],["gwas-for-multiple-snps.html", "8.14 GWAS for multiple SNPs", " 8.14 GWAS for multiple SNPs A GWAS performs the linear regression we just did, for every SNP in the dataset. We could write a for loop to do this in R ourselves, but it would be slow because there are 256,896 variants in the full VCF. Because GWAS is such a common approach, researchers have developed software to standardize this process and make it extremely efficient. The most popular software package for GWAS is called PLINK, which is preloaded into your Cloud session. PLINK is a “command line” tool, so we could either use it by working from the Terminal tab in Posit Cloud, or using the system() command within R. For this class we’ll use the latter approach. The system() command The command line is a text interface that takes in commands for your computer’s operating system to run. RStudio and Posit Cloud are a more interactive interface for writing code that you’d normally have to run on the command line. The system() command tells RStudio to run a snippet of command line code for you, without you having to leave the R environment. "],["gwas-of-one-snp-with-plink.html", "8.15 GWAS of one SNP with PLINK", " 8.15 GWAS of one SNP with PLINK First, we’ll replicate the GWAS that we did in R with just the first SNP of the VCF, rs9699599. # replicate first SNP association with PLINK system(command = "./plink --file genotypes --linear --allow-no-sex --snp rs9699599 --pheno GS451_IC50.txt --pheno-name GS451_IC50") Breakdown of the PLINK command ./plink: Use the PLINK software --file genotypes: Genotype data files (genotypes.map, genotypes.ped) begin with the string “genotypes” --linear: Run a linear additive association test for each SNP --allow-no-sex: Include samples we don’t have sex metadata for --snp rs9699599: Only run the analysis for a single SNP (rs9699599) --pheno GS451_IC50.txt: Phenotype data is located in a file called GS451_IC50.txt --pheno-name GS451_IC50: The column heading of the phenotype to use in the phenotype file is GS451_IC50 After running PLINK, we get an output file called plink.assoc.linear. Now look at the output of the plink.assoc.linear output file that PLINK produced. snp1 <- read.table("plink.assoc.linear", header = TRUE) head(snp1) ## CHR SNP BP A1 TEST NMISS BETA STAT P ## 1 1 rs9699599 558185 G ADD 85 1.385 2.036 0.04493 How do these results compare to performing the GWAS by hand? Notice that the beta (i.e., the “slope” or coefficient) and p-value perfectly matches the results we obtained previously with R. "],["gwas-of-all-snps-with-plink.html", "8.16 GWAS of all SNPs with PLINK", " 8.16 GWAS of all SNPs with PLINK Now let’s allow PLINK to run the statistical tests for all SNPs by removing the --snp flag. system(command = "./plink --file genotypes --linear --allow-no-sex --pheno GS451_IC50.txt --pheno-name GS451_IC50") The plink.assoc.linear file should now have ~260,000 lines. Load the file into R to look at the results: results <- read.table(file = "plink.assoc.linear", header = TRUE) %>% # order table by lowest pvalue arrange(P) head(results) ## CHR SNP BP A1 TEST NMISS BETA STAT P ## 1 19 rs7257475 20372113 T ADD 88 -3.008 -6.876 9.311e-10 ## 2 19 rs10413538 20370690 T ADD 86 -3.026 -6.805 1.395e-09 ## 3 21 rs2826383 20844081 A ADD 166 3.031 5.866 2.392e-08 ## 4 19 rs12972967 20358400 T ADD 89 -2.421 -5.939 5.760e-08 ## 5 2 rs1358578 51626897 A ADD 166 2.111 5.307 3.571e-07 ## 6 17 rs3094508 33137048 C ADD 89 3.532 5.230 1.156e-06 "],["plotting-gwas-results.html", "8.17 Plotting GWAS results", " 8.17 Plotting GWAS results The qq() and manhattan() functions in the qqman package let us easily create QQ and Manhattan plots to visualize our GWAS results. # qq plot using the P (pvalues) column qq(results$P) # manhattan plot manhattan(results) SNPs with low p-values occur in peaks of multiple variants. These are not independent associations, but rather groups of variants in LD. "],["top-gwas-snp.html", "8.18 Top GWAS SNP", " 8.18 Top GWAS SNP One common future direction for GWAS studies is following up on the top SNP(s). Read in top_snp.vcf, a VCF of just the top SNP in the dataset, so that we can plot boxplots of the top SNP genotype stratified by phenotype: # extract genotypes of the top SNP top_snp <- vcfR2tidy(read.vcfR("top_snp.vcf")) ## Scanning file to determine attributes. ## File attributes: ## meta lines: 27 ## header_line: 28 ## variant count: 1 ## column count: 185 ## Meta line 27 read in. ## All meta lines processed. ## gt matrix initialized. ## Character matrix gt created. ## Character matrix gt rows: 1 ## Character matrix gt cols: 185 ## skip: 0 ## nrows: 1 ## row_num: 0 ## Processed variant: 1 ## All variants processed ## Extracting gt element GT top_snp_gt <- top_snp$gt %>% drop_na() # merge with phenotype data gwas_data <- merge(top_snp_gt, phenotypes, by.x = "Indiv", by.y = "IID") # plot boxplots ggplot(data = gwas_data) + geom_boxplot(aes(x = gt_GT_alleles, y = GS451_IC50)) ## Warning: Removed 1 rows containing non-finite values (stat_boxplot). Other potential follow-up directions include: Investigating the genomic environment in the UCSC Genome Browser Looking at nearby haplotype structure with LDproxy Note that the genotype data we’re using come from the Yoruba population Using the Geography of Genetic Variants browser to find the global allele frequencies of the variant Search for SNP in a phenotype database to see if there are other associations with it "],["conclusion-6.html", "8.19 Conclusion", " 8.19 Conclusion We used genotype and simulated phenotype data from the 1000 Genomes Project to perform a genome-wide association study for variants associated with drug \\(\\mathrm{IC_{50}}\\). Using linear regression, we first did GWAS “by hand” on just one variant in the VCF. We fit a linear model to ask whether there’s a significant relationship between genotype and phenotype. We then used PLINK to perform this test on every SNP in the genome. We followed up on the top SNP from our GWAS by plotting boxplots of phenotype stratified by genotype. "],["homework-6.html", "8.20 Homework", " 8.20 Homework 8.20.0.1 Learning Objectives Interpret results of a GWAS Practice manipulating tabular data 8.20.0.2 Assignment Run a GWAS of \\(\\mathrm{IC_{50}}\\) for the drug CB1908, using the same genotype data as before. The phenotypes are located in CB1908_IC50.txt. Make a QQ plot and a Manhattan plot of your results. Do you have any genome-wide significant hits? Are they located in or near a gene? For the top GWAS hit, plot the phenotype stratified by genotype. (Use top_snp_hw.vcf to get the genotypes of the top hit.) Solution # perform association test with PLINK system(command = "./plink --file genotypes --linear --allow-no-sex --pheno CB1908_IC50.txt --pheno-name CB1908_IC50") # read in gwas results results <- read.table(file = "plink.assoc.linear", header = TRUE) %>% mutate(index = row_number()) %>% arrange(P) # qq plot qq(results$P) # manhattan plot manhattan(results) On the Manhattan plot, there’s one hit that reaches genome-wide significance. # view top GWAS hit results[1, ] ## CHR SNP BP A1 TEST NMISS BETA STAT P ## 1 12 rs10876043 49190411 G ADD 161 1.779 7.18 2.518e-11 From looking it up in the UCSC Genome Browser, rs10876043 lies within an intron of the DIP2B gene. Finally, we plot this SNP’s genotype stratified by phenotype, using top_snp_hw.vcf. # extract top SNP and convert to tidy df top_snp <- vcfR2tidy(read.vcfR("top_snp_hw.vcf")) ## Scanning file to determine attributes. ## File attributes: ## meta lines: 27 ## header_line: 28 ## variant count: 1 ## column count: 185 ## Meta line 27 read in. ## All meta lines processed. ## gt matrix initialized. ## Character matrix gt created. ## Character matrix gt rows: 1 ## Character matrix gt cols: 185 ## skip: 0 ## nrows: 1 ## row_num: 0 ## Processed variant: 1 ## All variants processed ## Extracting gt element GT # get genotype dataframe top_snp_gt <- top_snp$gt %>% drop_na() # read in phenotype dataframe phenotypes <- read.table("CB1908_IC50.txt", header = TRUE) # merge genotype and phenotype info gwas_data <- merge(top_snp_gt, phenotypes, by.x = "Indiv", by.y = "IID") # plot genotype by phenotype boxplots ggplot(data = gwas_data) + geom_boxplot(aes(x = gt_GT_alleles, y = CB1908_IC50)) ## Warning: Removed 2 rows containing non-finite values (stat_boxplot). "],["scans-for-selection.html", "9 Scans for selection", " 9 Scans for selection In this lab, we’ll explore three methods for identifying signatures of selection: FST, population branch statistic (PBS), and extended haplotype homozygosity (EHH). 9.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Describe the genetic signatures of selection and what they reveal about the strength and timing of the selective sweep. Calculate and interpret population differentiation with FST. Understand why PBS provides additional information over two-population tests of selection. Explain how EHH and iHS leverage haplotype information to identify selection. "],["signatures-of-positive-selection.html", "9.1 Signatures of positive selection", " 9.1 Signatures of positive selection A central question in human evolutionary genetics is what genetic adaptations humans acquired as they migrated into diverse environments. Fig. 1 (source). The history of human migrations. The process of evolutionary adaptation leaves characteristic signatures on patterns of population genetic variation. By developing statistics to capture these signatures and applying them to human genetic data, we can uncover evidence of past episodes of positive selection. Statistics for identifying signatures of selection can be broadly classified into two categories: frequency-based and haplotype-based. "],["frequency-based-signatures.html", "9.2 Frequency-based signatures", " 9.2 Frequency-based signatures One signature of selection is an allele whose frequency is either smaller or larger than you would expect. Fig. 2. The allele frequencies of this variant shows large differences between population. How do we determine the expected AF? We can compare AFs between populations. On average, neutrally evolving variants should have similar frequencies across populations. We can enrich for potential targets of selection by asking which variants show the biggest population-specific frequency differences. If a variant shows large AF differences and the populations in question share common ancestry – as all populations do – then the allele frequency must have changed in one population. We can also supplement this with knowledge about when the populations diverged to determine when and how quickly this AF change must have happened. "],["haplotype-based-signatures.html", "9.3 Haplotype-based signatures", " 9.3 Haplotype-based signatures When a variant changes in frequency, it doesn’t change alone. The variants on the haplotype surrounding it will be pulled along to high frequency. This phenomenon, called hitchhiking, is similar to the haplotype blocks we observe in GWAS result (and both are caused by linkage between variants). What do you expect to happen to genetic diversity in the region of a selective sweep? If one haplotype is sweeping to high AF, we expect that genetic diversity in the region decreases because it’s being replaced by the selected haplotype. This is called a selective sweep because variation is being “swept” out of the region. This decreased diversity signature fades over time as new mutations arise on the haplotype. Fig. 3. (A) Selective sweeps reduce genetic diversity. (B)-(D) Summary of common signatures of selection. What can the size of the linked haplotype tell us about its evolutionary history? Because recombination breaks down haplotypes over time, a longer haplotype implies more recent selection. It can also provide information on the strength of selection – if most occurrences of the haplotype in the population are unbroken, selection was strong enough that it didn’t have time to recombine during the sweep. "],["setup-5.html", "9.4 Setup", " 9.4 Setup 9.4.1 R packages In addition to tidyverse and vcfR, we’ll also be using ggtree, an R package for visualizing trees associated with PBS outliers. library(tidyverse) library(vcfR) library(ggtree) "],["the-fst-statistic.html", "9.5 The FST statistic", " 9.5 The FST statistic \\(\\mathbf{F_{ST}}\\) is a statistic that quantifies differences in allele frequencies between populations at one variable site. The version of \\(\\mathrm{F_{ST}}\\) that we’ll calculate today compares genotypic variance within subpopulations (“S”) against the total population (“T”). One way to conceptualize this is the deficiency of heterozygotes observed across subpopulations, relative to the proportion that would be expected under random mating (i.e., no population structure). We calculate this by taking the difference between: \\(\\mathbf{H_T}\\): The expected frequency of heterozygotes when individuals across all subpopulations are pooled \\(\\mathbf{mean(H_S)}\\): The mean frequency of heterozygotes, calculated within each subpopulation and then averaged where \\(H = 2pq\\), and \\(p\\) and \\(q\\) are the frequencies of the two alleles at a site \\[ \\textrm{F}_{ST} = \\frac{H_T - \\textrm{mean}(H_S)}{H_T} \\] \\(\\mathrm{F_{ST}}\\) ranges from 0 to 1: \\(\\mathrm{F_{ST}} = 0\\): No population structure (separating the subpopulations doesn’t affect heterozygosity estimates) \\(\\mathrm{F_{ST}} = 1\\): Subopulations are very different (ex: one population only carries one allele, while the other population only carries the other) See this Nature Review Genetics article for a more thorough discussion on the use and interpretation of \\(\\mathrm{F_{ST}}\\) and related statistics. "],["data-for-fst.html", "9.6 Data (for FST)", " 9.6 Data (for FST) We’ll calculate \\(\\mathrm{F_{ST}}\\) using genotype data from the 1000 Genomes Project. Read in the VCF using thevcfR package: # read genotype data with vcfR vcf <- read.vcfR(file = "random_variable_sites.vcf.gz") ## Scanning file to determine attributes. ## File attributes: ## meta lines: 19 ## header_line: 20 ## variant count: 9748 ## column count: 2513 ## Meta line 19 read in. ## All meta lines processed. ## gt matrix initialized. ## Character matrix gt created. ## Character matrix gt rows: 9748 ## Character matrix gt cols: 2513 ## skip: 0 ## nrows: 9748 ## row_num: 0 ## Processed variant 1000 Processed variant 2000 Processed variant 3000 Processed variant 4000 Processed variant 5000 Processed variant 6000 Processed variant 7000 Processed variant 8000 Processed variant 9000 Processed variant: 9748 ## All variants processed We’ll also read in a metadata table with information on which populations each sample is from. # read metadata metadata <- read.table("integrated_call_samples.txt", header = TRUE) head(metadata) ## sample pop superpop sex ## 1 HG00096 GBR EUR male ## 2 HG00097 GBR EUR female ## 3 HG00099 GBR EUR female ## 4 HG00100 GBR EUR female ## 5 HG00101 GBR EUR male ## 6 HG00102 GBR EUR female "],["the-genetic_diff-function.html", "9.7 The genetic_diff function", " 9.7 The genetic_diff function We’ll compute \\(\\textrm{F}_{ST}\\) using vcfR’s genetic_diff function. (This function technically calculates \\(\\textrm{G}_{ST}\\), a version of \\(\\textrm{F}_{ST}\\) that considers when there are more than two alleles at a given locus. When a locus is biallelic, \\(\\textrm{F}_{ST} = \\textrm{G}_{ST}\\).) ?genetic_diff genetic_diff requires: vcfR object (in our case, vcf) Factor indicating populations “Factor indicating populations” The second object for genetic_diff needs to be a vector (i.e., a list) of population labels for the samples in the VCF. These labels must be factors, which is an R data type that limits a variable to a set of values. In our case, these values are the specific population labels in our dataset. We’ll be using the superpopulation groupings for this calculation. We can use our metadata table to generate a vector of superpopulation labels. Since the superpopulation IDs are in the superpop column of that dataframe, we can convert the column from character to factor values with the as.factor function. pop_labels <- as.factor(metadata$superpop) head(pop_labels) ## [1] EUR EUR EUR EUR EUR EUR ## Levels: AFR AMR EAS EUR SAS Previewing pop_labels shows us that there are five “levels” in this vector, where each level is a superpopulation name. "],["calculating-fst.html", "9.8 Calculating FST", " 9.8 Calculating FST Run genetic_diff on the VCF: # calculate gst gst_results <- genetic_diff(vcf, pop_labels) %>% # order dataframe by descending gst value arrange(-Gst) # preview highest gst variants head(gst_results) ## CHROM POS Hs_AFR Hs_AMR Hs_EAS Hs_EUR Hs_SAS ## 1 chr21 17753762 0.3537087 0.20174987 0.1326531 0.029319019 0.040063399 ## 2 chr21 18668817 0.1477089 0.38831400 0.1377374 0.424382716 0.414679179 ## 3 chr21 15620159 0.4997750 0.09318240 0.0000000 0.007905014 0.000000000 ## 4 chr21 16235733 0.4994938 0.09318240 0.0000000 0.007905014 0.002042899 ## 5 chr21 22780904 0.4992826 0.09836474 0.0000000 0.001982159 0.000000000 ## 6 chr21 22786927 0.4991001 0.09318240 0.0000000 0.001982159 0.026231489 ## Ht n_AFR n_AMR n_EAS n_EUR n_SAS Gst Htmax Gstmax ## 1 0.3650242 1320 694 1008 1008 978 0.5572530 0.8286973 0.8049790 ## 2 0.4847713 1320 694 1008 1008 978 0.4082388 0.8484665 0.6618973 ## 3 0.2439190 1320 694 1008 1008 978 0.4004813 0.8289905 0.8235999 ## 4 0.2341095 1320 694 1008 1008 978 0.3739730 0.8290489 0.8232205 ## 5 0.2323592 1320 694 1008 1008 978 0.3732539 0.8288159 0.8242912 ## 6 0.2346916 1320 694 1008 1008 978 0.3609202 0.8297041 0.8192288 ## Gprimest ## 1 0.6922578 ## 2 0.6167706 ## 3 0.4862571 ## 4 0.4542805 ## 5 0.4528180 ## 6 0.4405610 # preview lowest gst variants tail(gst_results) ## CHROM POS Hs_AFR Hs_AMR Hs_EAS Hs_EUR Hs_SAS ## 9743 chr21 45527242 0.001514004 0.000000000 0.000000000 0.001982159 0.002042899 ## 9744 chr21 46135735 0.001514004 0.000000000 0.001982159 0.000000000 0.002042899 ## 9745 chr21 10718788 0.001514004 0.000000000 0.001982159 0.001982159 0.000000000 ## 9746 chr21 43949497 0.001514004 0.002877692 0.001982159 0.000000000 0.002042899 ## 9747 chr21 33087300 0.003025712 0.005747079 0.005934666 0.003960380 0.004081616 ## 9748 chr21 7948042 0.499885216 0.499995847 0.499968506 0.499992126 0.500000000 ## Ht n_AFR n_AMR n_EAS n_EUR n_SAS Gst Htmax Gstmax ## 9743 0.001197365 1320 694 1008 1008 978 3.251980e-04 0.7924231 0.9984895 ## 9744 0.001197365 1320 694 1008 1008 978 3.251980e-04 0.7924231 0.9984895 ## 9745 0.001197365 1320 694 1008 1008 978 3.150481e-04 0.7924255 0.9984895 ## 9746 0.001596168 1320 694 1008 1008 978 2.547455e-04 0.7924784 0.9979864 ## 9747 0.004383322 1320 694 1008 1008 978 1.475473e-04 0.7930368 0.9944736 ## 9748 0.499976954 1320 694 1008 1008 978 3.141686e-05 0.8960702 0.4420513 ## Gprimest ## 9743 3.256899e-04 ## 9744 3.256899e-04 ## 9745 3.155247e-04 ## 9746 2.552595e-04 ## 9747 1.483672e-04 ## 9748 7.107064e-05 genetic_diff outputs a table of \\(\\textrm{G}_{ST}\\) results, where every line corresponds to one variant from the input VCF. Our \\(\\textrm{G}_{ST}\\) values range from \\(0.0021\\) to \\(0.00033\\). "],["distribution-of-gst-across-the-genome.html", "9.9 Distribution of GST across the genome", " 9.9 Distribution of GST across the genome Plot the distribution of \\(\\textrm{G}_{ST}\\) values from genetic_diff ggplot(data = gst_results, aes(x = Gst)) + geom_histogram() ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. This is an exponentially decaying distribution, indicating that most common human variants don’t show strong differences in allele frequency between populations. "],["top-gst-hits.html", "9.10 Top GST hits", " 9.10 Top GST hits The variants with high \\(\\textrm{G}_{ST}\\) values should show differences in allele frequency between populations. Let’s examine the top-scoring variant: gst_results[1, ] ## CHROM POS Hs_AFR Hs_AMR Hs_EAS Hs_EUR Hs_SAS Ht ## 1 chr21 17753762 0.3537087 0.2017499 0.1326531 0.02931902 0.0400634 0.3650242 ## n_AFR n_AMR n_EAS n_EUR n_SAS Gst Htmax Gstmax Gprimest ## 1 1320 694 1008 1008 978 0.557253 0.8286973 0.804979 0.6922578 We can use the GGV browser to visualize this variant’s allele frequencies across the 1000 Genomes populations. One complicating factor is that the browser is based on the hg19 reference genome, while we’re working with a VCF on the more recent hg38 coordinate system. How do you compare variants between genome builds? There are many ways of converting from genome coordinate system to the other. One way is to look up the ID of the SNP in the UCSC Genome Browser, using its chromosome and position: Fig. 4. Identifying a SNP’s rsID in the UCSC Genome Browser. This SNP has the ID rs7276293, which should be consistent between reference builds. "],["viewing-gst-hits-in-ggv.html", "9.11 Viewing GST hits in GGV", " 9.11 Viewing GST hits in GGV Now we can navigate to the GGV browser and look up the distribution of allele frequencies for this variant. Note that the “position” has changed due to the new coordinate system, but we are looking at the same SNP. This variant has huge allele frequency differences across populations, consistent with the high GST value that we computed. Also note that two populations in the Americas also carry this variant at high frequency. These are both African American populations – African Caribbean in Barbados (ACB) and African Ancestry in SW USA (ASW). Fig. 5. Allele frequencies of our top GST hit. "],["population-branch-statistic.html", "9.12 Population branch statistic", " 9.12 Population branch statistic \\(\\textrm{F}_{ST}\\) and related statistics ask about allele frequency differences between two populations. If we compare sets of three populations instead of focusing on pairs, we can calculate a different statistic called the population branch statistic (PBS). What are the advantages of comparing three populations? Two-population comparisons tell us that an allele frequency change happened after the two populations diverged, but give us no information about when it occurred. Comparing between three populations lets us contrast allele frequencies among the populations to localize frequency changes to a particular branch of a tree. Fig. 6. A variant exists at different frequencies in populations A and B. By comparing to a third population, we can identify that selection likely occurred within population A. "],["calculating-pbs.html", "9.13 Calculating PBS", " 9.13 Calculating PBS PBS is based on calculating \\(\\textrm{F}_{ST}\\) for each pairwise comparison of the three populations. We then calculate the branch length (\\(\\mathbf{T}\\)) that separates each population pair: \\[ T = -\\mathrm{log}(1 - \\textrm{F}_{ST}) \\] PBS is then computed as: \\[ \\textrm{PBS} = \\frac{\\textrm{T}_{AB} + \\textrm{T}_{AC} - \\textrm{T}_{BC}}{2} \\] "],["data-for-pbs.html", "9.14 Data (for PBS)", " 9.14 Data (for PBS) We’ll calculate PBS using data from the paper: Tucci, S. et al. (2018). Evolutionary history and adaptation of a human pygmy population of Flores Island, Indonesia.. Flores Island was home to fossils of the archaic hominin species Homo floresiensis, also called “hobbits” because their skeletons are 3 ft. tall. It’s thought that H. floresiensis lived there until just 40k-30k years ago, overlapping with modern humans. This study collected samples from individuals who currently live on Flores Island and scanned their genomes for evidence of natural selection. They calculated PBS between: The Rampasasa (RPS) population from Flores A Han Chinese (CHB) population A Melanesian population from Papua New Guinea (PNG) Fig. 7. Distribution of populations used in Tucci et al. "],["reading-in-pbs-data.html", "9.15 Reading in PBS data", " 9.15 Reading in PBS data We’ve pre-calculated pairwise \\(\\textrm{F}_{ST}\\) between the Rampasasa, Han Chinese, and Papua New Guinea populations. Load the results for chromosome 11 into R: fst_results <- read.table("fst_results.txt.gz", header = TRUE) head(fst_results) ## chr pos rps.af chb.af png.af fst.rps.chb fst.rps.png ## 1 11 100001950 0.1666670 0.0145631 0.0428571 0.32524800 0.0845486 ## 2 11 100003476 0.0555556 0.0339806 0.1000000 -0.01078610 -0.0118052 ## 3 11 100004351 0.1111110 0.0485437 0.1142860 0.05945300 -0.0322152 ## 4 11 100005864 0.6111110 0.6553400 0.4285710 -0.02752900 0.0520164 ## 5 11 100006486 0.8333330 0.7766990 0.7571430 0.00768713 -0.0119055 ## 6 11 100006861 0.5000000 0.3834950 0.2285710 0.05413630 0.1807550 ## fst.png.chb ## 1 0.00465910 ## 2 0.03640770 ## 3 0.02896550 ## 4 0.11842600 ## 5 -0.00951234 ## 6 0.06338550 Every row of this table is a SNP: Columns ending in .af contain the allele frequency for that population Columns starting with fst. contain the \\(\\textrm{F}_{ST}\\) between that population pair "],["calculating-pbs-1.html", "9.16 Calculating PBS", " 9.16 Calculating PBS Using these \\(\\textrm{F}_{ST}\\) values, we can calculate (for every SNP) the branch lengths (\\(\\mathbf{T}\\)) that separate each population pair, and then calculate PBS. The mutate() function tidyverse’s mutate function is an easy way to perform calculations on tables. Its syntax is: mutate(new_column = <formula for calculating column values>) For example, if I wanted to create a new column that average each SNP’s allele frequencies across the three populations: fst_results %>% mutate(avg_af = (rps.af + chb.af + png.af) / 3) Filling in the gaps in the code block below, use mutate to calculate T and PBS on the FST values: pbs <- fst_results %>% # calculate branch lengths between populations mutate(T_rps_chb = _________, T_rps_png = _________, T_png_chb = _________,) %>% # calculate pbs mutate(pbs = _________) %>% # sort by descending pbs value arrange(-pbs) Solution pbs <- fst_results %>% # calculate branch lengths between populations mutate(T_rps_chb = -log(1 - fst.rps.chb), T_rps_png = -log(1 - fst.rps.png), T_png_chb = -log(1 - fst.png.chb)) %>% # calculate pbs mutate(pbs = ((T_rps_png + T_rps_chb) - (T_png_chb)) / 2) %>% # sort by descending pbs value arrange(-pbs) head(pbs) ## chr pos rps.af chb.af png.af fst.rps.chb fst.rps.png fst.png.chb ## 1 11 126880301 0.833333 0.296117 0.0571429 0.734021 0.823884 0.216269 ## 2 11 126883747 0.833333 0.296117 0.0571429 0.734021 0.823884 0.216269 ## 3 11 126893266 0.833333 0.300971 0.0571429 0.729450 0.823884 0.222408 ## 4 11 126883622 0.833333 0.300971 0.0571429 0.729227 0.823884 0.221887 ## 5 11 126888750 0.833333 0.305825 0.0571429 0.724490 0.823884 0.227770 ## 6 11 126885142 0.833333 0.320388 0.0571429 0.709721 0.823884 0.244928 ## T_rps_chb T_rps_png T_png_chb pbs ## 1 1.324338 1.736612 0.2436894 1.408630 ## 2 1.324338 1.736612 0.2436894 1.408630 ## 3 1.307298 1.736612 0.2515533 1.396179 ## 4 1.306474 1.736612 0.2508835 1.396102 ## 5 1.289131 1.736612 0.2584728 1.383635 ## 6 1.236913 1.736612 0.2809422 1.346291 "],["manhattan-plot-of-pbs-results.html", "9.17 Manhattan plot of PBS results", " 9.17 Manhattan plot of PBS results We can visualize our PBS results by generating a Manhattan plot where we plot PBS on the y-axis instead of p-values. Make this Manhattan plot using geom_point. ggplot(data = pbs, aes(x = pos, y = pbs)) + geom_point() As evidence of positive selection, we are interested in both the height of the peaks in the plot, as well as the number of SNPs that comprise each peak (which is a proxy for haplotype length). "],["top-pbs-hits.html", "9.18 Top PBS hits", " 9.18 Top PBS hits What are the top PBS hits we’ve identified? Click on the pbs table to scroll through the SNPs with the highest PBS values. Use the UCSC Genome Browser to look up the top two PBS peaks. (We’re using the hg19 browser here because this data was generated with the hg19 reference genome.) What genes (if any) do these top PBS peaks overlap with? The top chr11 peak doesn’t seem to overlap with any genes, but is closest to KIRREL3. The second chr11 peak overlaps with the fatty acid desaturase gene cluster (FADS1, FADS2, and FADS3), which have previously been implicated as targets of independent episodes of positive selection in human populations. Fig. 8. The FADS gene cluster around the second PBS peak. "],["plotting-pbs-trees.html", "9.19 Plotting PBS trees", " 9.19 Plotting PBS trees Another useful way to visualize PBS is by comparing trees for the top PBS outliers to the genome-wide average tree. Run the code blocks below to plot these trees: # create average tree tr_mean <- rtree(n = 3, rooted = FALSE, br = c(mean(pbs$T_rps_png), mean(pbs$T_rps_chb), mean(pbs$T_png_chb))) # plot average tree ggtree(tr_mean, layout = "daylight") + geom_treescale(width = 0.1) + geom_tiplab(label = c("RPS", "PNG", "CHB")) ## Average angle change [1] 0.407407407407407 ## Average angle change [2] 0 # create tree for top snp tr_top <- rtree(n = 3, rooted = FALSE, br = c(pbs[1,]$T_rps_png, pbs[1,]$T_rps_chb, pbs[1,]$T_png_chb)) # plot top snp tree ggtree(tr_top, layout = "daylight") + geom_treescale(width = 0.1) + geom_tiplab(label = c("RPS", "PNG", "CHB")) ## Average angle change [1] 0.407407407407407 ## Average angle change [2] 0 "],["extended-haplotype-homozygosity.html", "9.20 Extended haplotype homozygosity", " 9.20 Extended haplotype homozygosity The haplotype-based class of selection statistics quantifies long haplotypes that result from a selective sweep. Extended haplotype homozygosity (EHH) is defined as the probability that any two haplotypes in a population are homozygous at SNPs in specific genomic region. EHH should be elevated in regions under historical selection, because a sweep causes one haplotype to rise to high frequency, and decay as you move further from the site under selection. Fig. 9. EHH measures how likely two haplotypes are to carry the same variant at a given location – a signature that we expect recent selection to exaggerate. "],["plotting-ehh.html", "9.21 Plotting EHH", " 9.21 Plotting EHH EHH can be visualized with phylogeny-like plots like the one below. The width of the blue bar (the haplotype of interest) represents the haplotype’s frequency in a population, and the steps in the plot indicate historical recombination. The other branches of the phylogeny (in red) indicate other haplotypes in this region. An overrepresentation of one haplotype over the others creates the observation of extreme EHH. Fig. 10 (from David Reich). Overrepresentation of the blue haplotype indicates extreme EHH, a possible signature of selection. EHH plot for real data This plot shows EHH calculated for the CEU population of 1000 Genomes (Utah Residents [CEPH] with Northern and Western European Ancestry), zoomed in at the lactase (LCT) locus. A haplotype in this locus underwent a selective sweep in ancestor of European populations that allowed digestion of milk into adulthood, resulting in a present-day signature of EHH that stretches across megabases of sequence. In contrast, the ancestral haplotype (bottom) displays a much greater diversity and recombination. Fig. 11. EHH calculated for the lactase locus. "],["integrated-haplotype-statistic.html", "9.22 Integrated haplotype statistic", " 9.22 Integrated haplotype statistic If you calculate EHH for both the new and ancestral haplotypes at a locus, you can compare them to calculate the integrated haplotype statistic (iHS), which is the ratio of the area under the EHH curve for the derived and ancestral haplotypes. Fig. 12. Comparing the EHH of haplotypes carrying the derived and ancestral alleles to calculate iHS. "],["the-pophuman-browser.html", "9.23 The PopHuman browser", " 9.23 The PopHuman browser While some R packages exist to compute EHH and iHS (e.g., the rehh package), they require some tricky processing of VCF files. Moreover, these statistics have already been computed genome-wide for all of the populations in the 1000 Genomes dataset, available from the PopHuman browser. This browser lets you pull up results for several population genetic signatures. Look up the lactase (LCT) gene in the search bar, and then click Select tracks in the upper left-hand corner to choose: iHS for the CEU (European) population pi for the CEU population. This is a measure of nucleotide diversity, which we expect to be low in a region under historical selection Fig. 13. iHS and \\(\\pi\\) in the LCT region. Note that if we compare both of these statistics to the genome-wide mean (yellow lines), we can see how dramatically they deviate from expectations in this genomic region. "],["conclusion-7.html", "9.24 Conclusion", " 9.24 Conclusion In this lab, we used three approaches to identify selection in multi-population sequencing data. Using genotype data from the 1000 Genomes Project, we calculated FST, a measure of how different a variant’s allele frequency is between populations. We confirmed in the GGV Browser that the top FST variant shows strong population-specific AF differences. We then calculated the population branch statistic (PBS) to identify variants under selection in a human population on Flores Island, Indonesia. One of the top PBS hits was in the fatty acid desaturase gene cluster (FADS). Finally, we discussed extended haplotype homozygosity (EHH) and related statistics, which detect long haplotypes that result from a selective sweep. Using the PopHuman browser, we saw that the LCT locus – the most famous example of selection in humans – exhibits both elevated EHH and reduced genetic diversity (\\(\\pi\\)). "],["homework-7.html", "9.25 Homework", " 9.25 Homework 9.25.0.1 Learning Objectives Interpret multiple statistics for measuring selection Explain how specific statistics can give different results because they measure different genetic signatures 9.25.0.2 Assignment Read this review paper on genomic evidence of human local adaptation by Fan et al. Find examples of local adaptation (genes and populations) in the paper, and look up the relevant populations (or related populations) and tests of selection in the PopHuman browser. Are the signatures of selection apparent? Are the signature apparent based on all statistics? Why do certain statistics capture evidence of selection at certain loci but not others? "],["archaic-admixture.html", "10 Archaic admixture", " 10 Archaic admixture In this lab, we’ll discuss three common statistics, \\(D\\), \\(f_{4}\\), and the \\(f_{4}\\)-ratio, which are used for quantifying and testing hypotheses related to admixture (or “introgression”). 10.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Explain how incomplete lineage sorting can create patterns of allele sharing that are discordant with species relationships. Describe how introgression is expected to affect patterns of allele sharing. Interpret the \\(D\\) and \\(f_4\\) statistics and their associated p-values. Interpret the \\(f_{4}\\)-ratio ratio statistic and whether it implies differences in archaic admixture between populations. "],["neanderthal-and-denisovan-introgression.html", "10.1 Neanderthal and Denisovan introgression", " 10.1 Neanderthal and Denisovan introgression As modern humans migrated out of Africa 50,000-70,000 years ago, they encountered and intebred with two groups of archaic hominins, the Neanderthals and Denisovans. Admixture with archaic hominins resulted in introgression of archaic DNA into these migrating populations. These Neanderthal and Denisovan sequences still persist in the genomes of their present-day descendents. Fig. 1. Ancient encounters between migrating human populations and archaic hominins. "],["inferring-introgression-from-phylogenetic-trees.html", "10.2 Inferring introgression from phylogenetic trees", " 10.2 Inferring introgression from phylogenetic trees One test for introgression – called the \\(\\textbf{D}\\) statistic, or ABBA-BABA test – compares the phylogenetic tree of species-level relationships with the tree for a specific genetic variant. We expect the species-level tree for Neanderthals and humans to look like the white bars of the tree in Fig. 2, where any two human populations are more similar to each other than they are to Neanderthals or chimpanzees (the outgroup). If a genetic variant differs between humans and Neanderthals, we generally expect it to segregate according to the species-level tree, in an AABB pattern (Fig. 2). Fig. 2. A variant concordant with the species-level tree for modern humans and Neanderthals. "],["incomplete-lineage-sorting.html", "10.3 Incomplete lineage sorting", " 10.3 Incomplete lineage sorting More rarely, the tree constructed for a specific SNP is discordant with the species tree. This is usually due to incomplete lineage sorting (ILS) – when genetic variation is present in the ancestor of two populations (e.g., the modern human–Neanderthal ancestor), then randomly fixes in a fashion that happens to conflict with the populations’ evolutionary relationships. ILS can create discordant ABBA or BABA trees for a given SNP. Under ILS, we would expect to see approximately equal numbers of ABBA and BABA trees. Fig. 3. ABBA and BABA allele patterns can be formed by incomplete lineage sorting. "],["evidence-of-introgression.html", "10.4 Evidence of introgression", " 10.4 Evidence of introgression Discordant trees can also be produced by introgression. In this case, the B allele arises on the Neanderthal lineage and is passed from Neanderthals into a human population, creating either an ABBA or BABA pattern (depending on which population receives Neanderthal gene flow). Fig. 4. ABBA and BABA allele patterns formed by Neanderthal introgression. "],["the-d-statistic.html", "10.5 The \\(D\\) statistic", " 10.5 The \\(D\\) statistic Introgression creates an imbalance in the number of ABBA or BABA trees if only one of the human populations has admixed with Neanderthals. The \\(\\textbf{D}\\) statistic quantifies this imbalance: \\[ D = \\frac{\\textrm{# BABA sites} - \\textrm{# ABBA sites}}{\\textrm{# BABA sites} + \\textrm{# ABBA sites}} \\] \\(D > 0\\) is evidence for Neanderthal gene flow into the H2 population, while \\(D < 0\\) is evidence for gene flow into H1. Choice of populations for the \\(D\\) statistic The choice of populations is very important when calculating the \\(D\\) statistic. When assessing archaic introgression, H2 is typicaly set as a human population without archaic admixture (e.g., a population from Africa). If H2 instead were a European population that did possess introgressed sequence, we would not expect a significant \\(D\\) statistic. "],["setup-6.html", "10.6 Setup", " 10.6 Setup In this lab, we’ll quantify evidence for introgression in human populations using \\(D\\) and related statistics. 10.6.1 R packages In addition to tidyverse, we’ll use the admixr package, which allows us to easily run the software package ADMIXTOOLS from within R to calculate \\(D\\) and related statistics. The exercises for class were adapted from the admixr tutorial, available here. library(tidyverse) library(admixr) "],["data-3.html", "10.7 Data", " 10.7 Data The admixr package provides real example data from 10 human individuals, which can be acquired by running its download_data() function: # download data into current directory prefix <- download_data(dirname = ".") We now have a directory called snps that contain four files: snps.geno: Genotype of each individual (column) at each SNP (row) Represented as counts of the alternative allele (0, 1, 2) snps.ind: Population IDs for each individual snps.snp: SNP IDs, positions, and alleles regions.bed: A file of genomic regions (not required for basic admixr analysis) EIGENSTRAT format Together, the three .geno, .ind, and .snp files constitute EIGENSTRAT format. This is just a way of representing genotype data, similar to a VCF – in fact, several software packages exist to convert between VCF and EIGENSTRAT. "],["reading-in-data.html", "10.8 Reading in data", " 10.8 Reading in data We can provide the location of the downloaded files to the eigenstrat() function, which then constructs an EIGENSTRAT object to be used for downstream analysis. # read in eigenstrat files snps <- eigenstrat("./snps/snps") snps ## EIGENSTRAT object ## ================= ## components: ## ind file: ./snps/snps.ind ## snp file: ./snps/snps.snp ## geno file: ./snps/snps.geno "],["the-d-function.html", "10.9 The d() function", " 10.9 The d() function admixr computes the \\(D\\) statistic in a function called d(). ?d As input, d() asks for: Data object in EIGENSTRAT format Four population names (W, X, Y, Z) to calculate D between "],["computing-the-d-statistic.html", "10.10 Computing the D statistic", " 10.10 Computing the D statistic Let’s compute \\(D\\) for four of the individuals we have data for: French, Sardinian, Vindija (Neanderthal), and chimpanzee. d_result <- d(data = snps, # provide population names to calculate D between W = "French", X = "Sardinian", Y = "Vindija", Z = "Chimp") d_result ## W X Y Z D stderr Zscore BABA ABBA nsnps ## 1 French Sardinian Vindija Chimp 0.0038 0.0074 0.511 10974 10891 487843 How do we interpret these results? The last three columns count the number of ABBA and BABA sites, as well as the total number of variants being analyzed. First, note that the ABBA/BABA sites are only a small fraction of the total number of variants – most variants conform to the species-level tree. The number of ABBA and BABA variants also looks similar, which implies that the discordant trees in these four populations primarily result from ILS rather than introgression. The middle columns give the actual value of \\(D\\) and its standard error, as well as the Z score (which is equal to \\(\\frac{D}{\\textrm{stderr}}\\)). "],["converting-to-p-values.html", "10.11 Converting to p-values", " 10.11 Converting to p-values How do we know whether the ABBA-BABA counts are significantly different? We can convert the Z score into a p-value: d_result <- d_result %>% # convert z score into pvalue mutate(p = 2 * pnorm(-abs(Zscore))) d_result ## W X Y Z D stderr Zscore BABA ABBA nsnps ## 1 French Sardinian Vindija Chimp 0.0038 0.0074 0.511 10974 10891 487843 ## p ## 1 0.6093511 Interpretation of this p-value The p-value does not look significant (no introgression into the ancestors of this French or Sardinian individual). This is in line with our observation that there doesn’t seem to be a disproportionate amount of ABBA or BABA sites. "],["computing-d-for-all-populations.html", "10.12 Computing D for all populations", " 10.12 Computing D for all populations We can give d() a list of populations to compute the \\(D\\) statistic for, where: W: A vector of our populations of interest X: An assumed unadmixed population (Yoruba) Y: The introgressing population (Vindija Neanderthal) Z: Outgroup (chimpanzee) # create vector of populations of interest pops <- c("French", "Sardinian", "Han", "Papuan", # including three African populations "Khomani_San", "Mbuti", "Dinka") # calculate D d_result <- d(data = snps, W = pops, X = "Yoruba", Y = "Vindija", Z = "Chimp") %>% # convert z score into pvalue mutate(p = 2 * pnorm(-abs(Zscore))) d_result ## W X Y Z D stderr Zscore BABA ABBA nsnps ## 1 French Yoruba Vindija Chimp 0.0313 0.006933 4.510 15802 14844 487753 ## 2 Sardinian Yoruba Vindija Chimp 0.0287 0.006792 4.222 15729 14852 487646 ## 3 Han Yoruba Vindija Chimp 0.0278 0.006609 4.199 15780 14928 487925 ## 4 Papuan Yoruba Vindija Chimp 0.0457 0.006571 6.953 16131 14721 487694 ## 5 Khomani_San Yoruba Vindija Chimp 0.0066 0.006292 1.051 16168 15955 487564 ## 6 Mbuti Yoruba Vindija Chimp -0.0005 0.006345 -0.074 15751 15766 487642 ## 7 Dinka Yoruba Vindija Chimp -0.0009 0.006124 -0.151 15131 15159 487667 ## p ## 1 6.482763e-06 ## 2 2.421441e-05 ## 3 2.680963e-05 ## 4 3.575987e-12 ## 5 2.932586e-01 ## 6 9.410104e-01 ## 7 8.799757e-01 Interpretation of \\(D\\) results This is the result that was published in Green et al. 2010, revealing evidence for gene flow from Neanderthals into the ancestors of non-African populations. We see significant evidence of Neanderthal introgression into the genomes of the non-African samples (French, Sardinian, Han, Papuan), but not the African samples (although we know from recent research that this is an oversimplification). "],["plotting-the-d-statistic.html", "10.13 Plotting the D statistic", " 10.13 Plotting the D statistic Use this code to plot the \\(D\\) statistic and standard error calculated for each population. This is a visual representation of the data in the d_result table: ggplot(data = d_result, aes(x = W, y = D, color = p < 0.05)) + geom_point() + geom_hline(yintercept = 0, linetype = 2) + geom_errorbar(aes(ymin = D - 1.96 * stderr, ymax = D + 1.96 * stderr), width = 0.5) + xlab("Population") "],["f_4-statistic.html", "10.14 \\(f_{4}\\) statistic", " 10.14 \\(f_{4}\\) statistic The \\(\\mathbf{f_{4}}\\) statistic – not to be confused with the \\(\\mathrm{F_{ST}}\\) from the previous week – is very similar to the D statistic. Its main advantage is that it is proportional to the branch length separating two pairs of populations. Compute the \\(f_{4}\\) statistic for all populations using the code below: f4_result <- f4(data = snps, W = pops, X = "Yoruba", Y = "Vindija", Z = "Chimp") %>% # convert z score into pvalue mutate(p = 2 * pnorm(-abs(Zscore))) f4_result ## W X Y Z f4 stderr Zscore BABA ABBA nsnps ## 1 French Yoruba Vindija Chimp 0.001965 0.000437 4.501 15802 14844 487753 ## 2 Sardinian Yoruba Vindija Chimp 0.001798 0.000427 4.209 15729 14852 487646 ## 3 Han Yoruba Vindija Chimp 0.001746 0.000418 4.178 15780 14928 487925 ## 4 Papuan Yoruba Vindija Chimp 0.002890 0.000417 6.924 16131 14721 487694 ## 5 Khomani_San Yoruba Vindija Chimp 0.000436 0.000415 1.051 16168 15955 487564 ## 6 Mbuti Yoruba Vindija Chimp -0.000030 0.000410 -0.074 15751 15766 487642 ## 7 Dinka Yoruba Vindija Chimp -0.000057 0.000380 -0.151 15131 15159 487667 ## p ## 1 6.763451e-06 ## 2 2.565034e-05 ## 3 2.940837e-05 ## 4 4.390659e-12 ## 5 2.932586e-01 ## 6 9.410104e-01 ## 7 8.799757e-01 Note that the p-values are the same as when we calculated the \\(D\\) statistic, but the actual \\(f_4\\) values are different. "],["f_4-ratio-statistic.html", "10.15 \\(f_{4}\\)-ratio statistic", " 10.15 \\(f_{4}\\)-ratio statistic The branch length proportionality of the \\(f_4\\) statistic is useful for deriving yet another statistic, called the \\(\\mathbf{f_{4}}\\)-ratio statistic. As implied by its name, this simply a ratio of two different \\(f_{4}\\) statistics. Unlike \\(D\\) and \\(f_{4}\\), the \\(f_{4}\\)-ratio tells us how much Neanderthal ancestry a given individual possesses. Calculate the \\(f_{4}\\)-ratio using the code block below: f4_ratio_result <- f4ratio(data = snps, X = pops, A = "Altai", B = "Vindija", C = "Yoruba", O = "Chimp") %>% # convert z score to pvalue mutate(p = 2 * pnorm(-abs(Zscore))) f4_ratio_result ## A B X C O alpha stderr Zscore p ## 1 Altai Vindija French Yoruba Chimp 0.023774 0.006176 3.850 1.181178e-04 ## 2 Altai Vindija Sardinian Yoruba Chimp 0.024468 0.006071 4.031 5.554004e-05 ## 3 Altai Vindija Han Yoruba Chimp 0.022117 0.005892 3.754 1.740349e-04 ## 4 Altai Vindija Papuan Yoruba Chimp 0.037311 0.005812 6.420 1.362743e-10 ## 5 Altai Vindija Khomani_San Yoruba Chimp 0.003909 0.005913 0.661 5.086123e-01 ## 6 Altai Vindija Mbuti Yoruba Chimp 0.000319 0.005717 0.056 9.553418e-01 ## 7 Altai Vindija Dinka Yoruba Chimp -0.001500 0.005394 -0.278 7.810124e-01 For this statistic, alpha represents the proportion of the genome whose ancestry traces to Neanderthal introgression. "],["plotting-f_4-ratio-results.html", "10.16 Plotting \\(f_{4}\\)-ratio results", " 10.16 Plotting \\(f_{4}\\)-ratio results Run the code below to plot the \\(f_{4}\\)-ratio values we computed: ggplot(data = f4_ratio_result, aes(x = X, y = alpha, color = p < 0.05)) + geom_point() + geom_errorbar(aes(ymin = alpha - 2 * stderr, ymax = alpha + 2 * stderr), width = 0.5) + geom_hline(yintercept = 0, linetype = 2) + labs(y = "Neanderthal ancestry proportion", x = "Present-day individual") Based on what we know about Papuan populations, do you think the estimate of 4% Neanderthal introgressed DNA is accurate? We know that Oceanian populations also experienced introgression from Denisovans. Denisovans were more genetically similar to Neanderthals than to modern humans, so Denisovan ancestry is being counted as Neanderthal ancestry by this metric. "],["computing-statistics-in-genomic-intervals.html", "10.17 Computing statistics in genomic intervals", " 10.17 Computing statistics in genomic intervals We’ve so far computed the \\(D\\), \\(f_4\\), and \\(f_4\\)-ratio statistics across the entire genome, but we can also restrict computation to particular genomic intervals, such as genes, promoters, enhancers, etc. What would region-specific differences imply? Region-specific differences suggest that there are some regions of the genome that are particularly tolerant or intolerant to introgression. Fig. 5 (source). Proportion of introgressed Neanderthal ancestry within specific gene annotations. In the figure below, we see that the genome-wide average percentage of Neanderthal ancestry is ~2%, but there are some genomic regions (promoters, evolutionarily conserved sequences) where this percentage is lower. One theory explaining this pattern is that Neanderthals accumulated a genetic load of slightly deleterious mutations due to their small population sizes. Consequently, when Neanderthal sequences were introgressed into human populations, they were subjected to negative selection, which was stronger in more functionally important regions of the genome. "],["bed-files.html", "10.18 BED files", " 10.18 BED files Annotations of genomic intervals are commonly represented in a file format called BED. We can utilize these files in admixr’s filter_bed() function, which excludes or restricts analyses to genomic intervals within a BED file. Run the code below to re-calculate the \\(f_4\\)-ratio with promoters_hg19.bed – a bed file containing the coordiinates for promoters annotated in the Ensembl Regulatory Build. We can create a new snps data object that either keeps or excludes these regions from our analysis. # get the path to the `regions.bed` file bed <- file.path("promoters_hg19.bed") # option 1: KEEP only these regions for analysis new_snps_keep <- filter_bed(snps, bed) # option 2: REMOVE these regions from analysis new_snps_remove <- filter_bed(snps, bed, remove = TRUE) "],["region-specific-f_4-ratio.html", "10.19 Region-specific \\(f_4\\) ratio", " 10.19 Region-specific \\(f_4\\) ratio Now we can re-calculate the \\(f_4\\)-ratio only within promoter regions. # f4-ratio with only promoters f4_filtered <- f4ratio(data = new_snps_keep, X = pops, A = "Altai", B = "Vindija", C = "Yoruba", O = "Chimp") %>% # convert z score to pvalue mutate(p = 2 * pnorm(-abs(Zscore))) f4_filtered ## A B X C O alpha stderr Zscore p ## 1 Altai Vindija French Yoruba Chimp -0.005541 0.028515 -0.194 0.84617588 ## 2 Altai Vindija Sardinian Yoruba Chimp 0.002263 0.031027 0.073 0.94180612 ## 3 Altai Vindija Han Yoruba Chimp 0.066668 0.029767 2.240 0.02509092 ## 4 Altai Vindija Papuan Yoruba Chimp 0.010940 0.030057 0.364 0.71585801 ## 5 Altai Vindija Khomani_San Yoruba Chimp 0.026367 0.031975 0.825 0.40937159 ## 6 Altai Vindija Mbuti Yoruba Chimp 0.005176 0.030194 0.171 0.86422377 ## 7 Altai Vindija Dinka Yoruba Chimp 0.008542 0.026768 0.319 0.74972651 Plot the region-excluded \\(f_4\\)-ratios ggplot(f4_filtered, aes(x = X, y = alpha, color = p < 0.05)) + geom_point() + geom_errorbar(aes(ymin = alpha - 2 * stderr, ymax = alpha + 2 * stderr), width = 0.5) + geom_hline(yintercept = 0, linetype = 2) + labs(y = "Neanderthal ancestry proportion", x = "Present-day individual") Except for the Han population, we see almost no Neanderthal ancestry when we calculate the \\(f_4\\)-ratio within promoters – supporting the idea that functionally important genomic regions are depleted for Neanderthal introgression. "],["conclusion-8.html", "10.20 Conclusion", " 10.20 Conclusion In this lab, we assessed evidence for Neanderthal introgression into specific human populations. We reviewed the \\(\\mathbf{D}\\) statistic, which asks whether a variant shows an imbalance in the population inheritance patterns expected from incomplete lineage sorting (ILS). Such an imbalance implies historical introgression into one population. With admixr, we calculated the \\(D\\) statistic for one individual from each of seven modern human populations, identifying significant evidence for Neanderthal introgression into the ancestors of non-African – but not African – populations. We also calculated the \\(\\mathbf{f_4}\\) statistic, which is very similar to the \\(D\\) statistic but is proportional to the genetic distance between two populations. We computed the \\(\\mathbf{f_4}\\)-ratio, whose value indicates the proportion of introgressed ancestry in each population. Finally, we computed the \\(\\mathbf{f_4}\\)-ratio within just promoter regions, where we observed a depletion of Neanderthal ancestry. "],["homework-8.html", "10.21 Homework", " 10.21 Homework 10.21.0.1 Learning Objectives Practice calculating introgression statistics in admixr Interpret the biological significance of region-specific values of the \\(f_4\\)-ratio 10.21.0.2 Assignment Follow these steps to create your own genome stratifications for calculating the \\(f_4\\) ratio statistic. Go to the UCSC Table Browser, where you can find a wide selection of annotations for the human genome. Make sure you set the assembly: drop-down box to Feb. 2009 (GRCh37/hg19). Use the group: and track: menus to select any set of genomic regions. You can click the data format description button and scroll to the Description section to find out what each annotation represents. Under the Retrieve and display data section, set the output format: to BED. Enter an output filename: (ex: all_genes.bed). Click get output to download the file. In Posit Cloud, upload your file using the Upload button in the Files panel (bottom right). Run the code block below to reformat the BED file. The code matches the UCSC’s chromosome naming format with the format used in the snps data: # fill in blank with the name of your bed file system(command = "sed -i 's/chr//g' ________") # get the path to your bed file bed <- file.path("________") Compute the \\(f_4\\) ratio statistic within and outside of the genomic intervals. Repeat for another set of genome annotations to contrast Neanderthal ancestry in different genomic elements. Solution Download tracklist of haploinsufficient genes (Phenotype and Literature -> Haploinsufficiency). # get the path to the `regions.bed` file bed <- file.path("haploinsufficient.bed") # option 1: KEEP only these regions for analysis new_snps_keep <- filter_bed(snps, bed) # option 2: REMOVE these regions from analysis new_snps_remove <- filter_bed(snps, bed, remove = TRUE) Re-calculate the \\(f_4\\)-ratio: # f4-ratio with the regions kept f4_keep <- f4ratio(data = new_snps_keep, X = pops, A = "Altai", B = "Vindija", C = "Yoruba", O = "Chimp") %>% # convert z score to pvalue mutate(p = 2 * pnorm(-abs(Zscore))) f4_keep ## A B X C O alpha stderr Zscore p ## 1 Altai Vindija French Yoruba Chimp 0.030580 0.009385 3.258 1.122004e-03 ## 2 Altai Vindija Sardinian Yoruba Chimp 0.018057 0.009117 1.981 4.759127e-02 ## 3 Altai Vindija Han Yoruba Chimp 0.023127 0.009617 2.405 1.617247e-02 ## 4 Altai Vindija Papuan Yoruba Chimp 0.036462 0.008964 4.068 4.741838e-05 ## 5 Altai Vindija Khomani_San Yoruba Chimp -0.001223 0.008774 -0.139 8.894501e-01 ## 6 Altai Vindija Mbuti Yoruba Chimp -0.015781 0.009100 -1.734 8.291808e-02 ## 7 Altai Vindija Dinka Yoruba Chimp -0.004929 0.008235 -0.599 5.491729e-01 # f4-ratio with the regions removed f4_remove <- f4ratio(data = new_snps_remove, X = pops, A = "Altai", B = "Vindija", C = "Yoruba", O = "Chimp") %>% # convert z score to pvalue mutate(p = 2 * pnorm(-abs(Zscore))) f4_remove ## A B X C O alpha stderr Zscore p ## 1 Altai Vindija French Yoruba Chimp 0.016554 0.007929 2.088 3.679783e-02 ## 2 Altai Vindija Sardinian Yoruba Chimp 0.027980 0.007826 3.575 3.502279e-04 ## 3 Altai Vindija Han Yoruba Chimp 0.020285 0.007348 2.761 5.762468e-03 ## 4 Altai Vindija Papuan Yoruba Chimp 0.036136 0.007550 4.786 1.701381e-06 ## 5 Altai Vindija Khomani_San Yoruba Chimp 0.005713 0.007593 0.752 4.520511e-01 ## 6 Altai Vindija Mbuti Yoruba Chimp 0.009803 0.007233 1.355 1.754176e-01 ## 7 Altai Vindija Dinka Yoruba Chimp -0.000663 0.006798 -0.097 9.227264e-01 Some of the alpha values for each population change when excluding/restricting to haploinsufficient genes, but their standard error ranges still overlap between the two \\(f_4\\)-ratio calculations, so they likely aren’t truly different. "],["gene-expression.html", "11 Gene expression", " 11 Gene expression In this lab, we’ll use data from the Genotype-Tissue Expression (GTEx) Project to explore how genetic variation impacts gene expression. 11.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Define expression and splicing quantitative trait loci. Explain the challenge of multiple testing in eQTL studies and how it is typically handled. Navigate the GTEx Portal to find expression data for genes of interest. "],["gene-expression-1.html", "11.1 Gene expression", " 11.1 Gene expression In this class, we’ve mostly discussed variation at the level of DNA sequence. However, variation in gene expression – and how it interacts with genotype data – is an equally important aspect of phenotype diversity. Measuring gene expression Sequencing mRNA molecules (RNA sequencing), aligning them to a reference genome, and counting the reads per gene provides us with a proxy for measuring expression level. Fig. 1 (source). Counting transcript expression from RNA-seq reads. "],["the-genotype-tissue-expression-project.html", "11.2 The Genotype-Tissue Expression project", " 11.2 The Genotype-Tissue Expression project In 2010, the NIH launched the first large-scale dataset of gene expression data, called the Genotype-Tissue Expression (GTEx) project. The final version of this dataset (v8) was released in 2020. GTEx is currently the most comprehensive gene expression dataset in existence. It involved the sequencing of whole genomes (DNA-seq) as well as transcriptomes (RNA-seq) from 948 recently-deceased individuals, with up to 54 tissues sampled throughout their bodies. One of the main motivations of GTEx was to better understand the genetic control of gene expression. How does genetic variation contribute to variation in amount, splicing, and tissue specificity of expressed RNA? Fig. 2 (source). Summary of individuals sequenced by GTEx. "],["gtex-portal.html", "11.3 GTEx portal", " 11.3 GTEx portal The GTEx Portal provides an interface to summarize and visualize these data. In the search bar, we can look up a gene of interest and see: Violin plots depicting inter-individual variation in gene expression across all tissues Variants that impact expression or splicing of that gene Fig. 3 (source). Distributions of gene expression across tissues for the DNMT3A gene. "],["genetic-effects-on-gene-expression.html", "11.4 Genetic effects on gene expression", " 11.4 Genetic effects on gene expression Why does expression for the same gene vary across individuals? There are many factors that can contribute to variability in gene expression in a population: Environment (ex: diet, climate, disease) Stochasticity/noise Epigenetics (methylation, repressive/activating histone marks) Genetics (genetic variants in promoter, enhancer, etc. sequences) How do we discover genetic variants that influence gene expression? We can perform a genome-wide association study, similar to what we would do for an organismal phenotype like height. This time, our phenotype is the expression of a specific gene, and we can search for genetic variants that impact this expression. "],["expression-qtls.html", "11.5 Expression QTLs", " 11.5 Expression QTLs The variants we identify with this GWAS approach are called expression quantitative trait loci (eQTLs). Notably, because the number of phenotypes we have is equal to the number of genes we’re testing, we would have to perform ~20,000 GWASs (the number of gemes) for every eQTL study in humans, and test ~5 million SNPs per GWAS. Multiple testing in eQTL studies When we’re performing this many repeated tests, you run the risk that any hits you find are just due to chance. In a GWAS, we would use multiple testing correction to account for this. However, because of the overwhelming number of tests we need to perform to identify eQTLs, our significance threshold would be so low that we likely wouldn’t discover anything. Reducing the number of tests In order to reduce the number of tests, we typically focus on eQTL mapping just in in the region around the gene body, which dramatically decreases the number of SNPs we’re testing. The rationale for this approach is that nearby regulatory regions (promoters, enhancers, etc.) are more likely to influence expression. Fig. 4. eQTL studies typically restrict their QTL search space to variants within 1 Mb of the gene. "],["eqtls-in-the-gtex-portal.html", "11.6 eQTLs in the GTEx Portal", " 11.6 eQTLs in the GTEx Portal The GTEx Portal includes an option to view all significant eQTLs for a gene, below the plots of tissue expression. Note that these eQTLs are labeled by tissue – they may not impact transcription outside of that tissue. Fig. 5. Significant eQTLs for DNMT3A in the GTEx Portal. eQTL violin plots The Actions column provides quick access to several visualizations of each eQTL, including a violin plot that shows how it impacts expression: Fig. 6. The T allele at the chr2_25264228_C_T_b38 SNP decreases DNMT3A expression. "],["splicing-qtls.html", "11.7 Splicing QTLs", " 11.7 Splicing QTLs In addition to variants that impact gene expression, there are splicing quantitative trait loci (sQTLs) that alter how a gene is spliced. Some sQTL mechanisms include: Create or destroying a splicing donor/acceptor site Changing the binding site for a protein that regulates splicing Altering a splicing factor protein itself Fig. 7. sQTLs may alter splice donor/acceptor sites, or binding sites for transcription factors that regulate splicing. sQTLs in GTEx The GTEx Portal also provides a list of sQTLs for each gene. Note that the violin plots for these QTLs refer to a specific intron of DNMT3A whose inclusion rate is affected by each SNP. Fig. 8. The A allele at the chr2_25530386_G_A_b38 SNP reduces excision of the chr2:25246776:25247051:clu_42604 intron of DNMT3A. "],["setup-7.html", "11.8 Setup", " 11.8 Setup Now we’ll look at the GTEx data ourselves to perform our own gene expression analyses. 11.8.1 R packages In addition to tidyverse, we’ll also load the MASS package, which is useful for various statistical functions. library(tidyverse) library(MASS) "],["data-4.html", "11.9 Data", " 11.9 Data The GTEx Portal provides links for downloading curated and summarized forms of its data, including giant matrices that encode the expression of every gene across all samples and tissues. For ease of manipulation in R, we’ve subset this data to 150 samples, highly expressed genes, and only data from liver and lung tissue. gtex <- read.table("gtex_subset.txt.gz", header = TRUE) head(gtex) ## Sample Age Sex Death_Hardy Tissue Gene_ID Gene_Name Counts ## 1 GTEX-111YS 60-69 M 0 Lung ENSG00000187634.11 SAMD11 59 ## 2 GTEX-111YS 60-69 M 0 Lung ENSG00000188976.10 NOC2L 2789 ## 3 GTEX-111YS 60-69 M 0 Lung ENSG00000187961.13 KLHL17 716 ## 4 GTEX-111YS 60-69 M 0 Lung ENSG00000187583.10 PLEKHN1 47 ## 5 GTEX-111YS 60-69 M 0 Lung ENSG00000187642.9 PERM1 23 ## 6 GTEX-111YS 60-69 M 0 Lung ENSG00000188290.10 HES4 534 The columns of this dataframe are: Sample: Individual sequenced Age: Individual’s age range Sex: Individual’s sex Death_Hardy: Individual’s cause of death, measured on the Hardy Scale Tissue: Tissue measured Gene_ID: Ensembl gene ID Gene_Name: The common gene name Counts: Expression level for the gene Ex: GTEX-111YS has 59 sequencing reads that mapped to the SAMD11 gene Data normalization The expression levels in this table have been normalized to account for factors such as sequencing variation between samples – i.e., if we collected more sequencing data from one individual than another. "],["differential-gene-expression.html", "11.10 Differential gene expression", " 11.10 Differential gene expression Using this dataset, we can fit regression models to ask about differences in gene expression between conditions. For example, let’s say we’re interested in whether the ACE2 gene – the receptor bound by the SARS-CoV-2 virus – exhibits differences in expression between males and females. First we subset the data to the relevant gene and tissue (ACE2 and lung) for our test: subset <- gtex %>% # filter for tissue and gene of interest filter(Tissue == "Lung" & Gene_Name == "ACE2") head(subset) ## Sample Age Sex Death_Hardy Tissue Gene_ID Gene_Name Counts ## 1 GTEX-111YS 60-69 M 0 Lung ENSG00000130234.10 ACE2 640 ## 2 GTEX-1128S 60-69 F 2 Lung ENSG00000130234.10 ACE2 64 ## 3 GTEX-11DXX 60-69 F 0 Lung ENSG00000130234.10 ACE2 236 ## 4 GTEX-11DXZ 50-59 M 0 Lung ENSG00000130234.10 ACE2 174 ## 5 GTEX-11EMC 60-69 F 2 Lung ENSG00000130234.10 ACE2 162 ## 6 GTEX-11EQ9 30-39 M 2 Lung ENSG00000130234.10 ACE2 85 Then we can fit a model to our data. Note that we’re using the glm.nb function, which uses a negative binomial distribution – good for modeling discrete (i.e., non-continuous) data, such as sequencing read counts. # fit model and print summary model <- glm.nb(formula = Counts ~ factor(Sex), data = subset) summary(model) ## ## Call: ## glm.nb(formula = Counts ~ factor(Sex), data = subset, init.theta = 0.9820746913, ## link = log) ## ## Deviance Residuals: ## Min 1Q Median 3Q Max ## -2.0205 -0.9991 -0.5441 -0.0219 4.9984 ## ## Coefficients: ## Estimate Std. Error z value Pr(>|z|) ## (Intercept) 5.5530 0.1709 32.494 < 2e-16 *** ## factor(Sex)M -0.7907 0.2121 -3.727 0.000194 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## (Dispersion parameter for Negative Binomial(0.9821) family taken to be 1) ## ## Null deviance: 129.67 on 99 degrees of freedom ## Residual deviance: 115.01 on 98 degrees of freedom ## AIC: 1214.5 ## ## Number of Fisher Scoring iterations: 1 ## ## ## Theta: 0.982 ## Std. Err.: 0.123 ## ## 2 x log-likelihood: -1208.475 Does sex impact ACE2 expression? The p-value is significant (p = 0.000194), suggesting that sex does affect ACE2 expression. Based on the coefficient of -0.7907, it looks like males tend to have ~0.8 fewer ACE2 transcripts in lung tissue. "],["conclusion-9.html", "11.11 Conclusion", " 11.11 Conclusion In this lab, we explored the GTEx dataset to understand how genetic variation impacts gene expression. We can treat gene expression as a phenotype to search for expression and splicing QTLs, the same way we would look for variants associated with an organismal trait. Due to the multiple testing burden of testing millions of variants across thousands of genes, eQTL studies typically limit themselves to variants close to the gene body. The GTEx Portal provides a convenient interface for browsing QTL and gene expression information across tissues. "],["homework-9.html", "11.12 Homework", " 11.12 Homework 11.12.0.1 Learning Objectives Become familiar with the data available in the GTEx dataset Interpret linear models in the context of gene expression 11.12.0.2 Assignment Fit a regression model (or multiple!) to the GTEx data we downloaded in class and test for differential expression between two (or more) conditions. For example, you could look at another gene, compare between tissues, age groups, or Hardy classifications, etc. Based on the results, does the condition affect expression of your gene? Solution As an example, we’ll test for differences in ACE2 expression between liver and lung tissue. First we subset the GTEx data to just the ACE2 gene: subset <- gtex %>% # filter gene of interest filter(Gene_Name == "ACE2") head(subset) ## Sample Age Sex Death_Hardy Tissue Gene_ID Gene_Name Counts ## 1 GTEX-111YS 60-69 M 0 Lung ENSG00000130234.10 ACE2 640 ## 2 GTEX-1128S 60-69 F 2 Lung ENSG00000130234.10 ACE2 64 ## 3 GTEX-11DXX 60-69 F 0 Lung ENSG00000130234.10 ACE2 236 ## 4 GTEX-11DXZ 50-59 M 0 Liver ENSG00000130234.10 ACE2 211 ## 5 GTEX-11DXZ 50-59 M 0 Lung ENSG00000130234.10 ACE2 174 ## 6 GTEX-11EMC 60-69 F 2 Lung ENSG00000130234.10 ACE2 162 Then we fit a model with glm.nb: # fit model and print summary model <- glm.nb(formula = Counts ~ factor(Tissue), data = subset) summary(model) ## ## Call: ## glm.nb(formula = Counts ~ factor(Tissue), data = subset, init.theta = 1.034483188, ## link = log) ## ## Deviance Residuals: ## Min 1Q Median 3Q Max ## -1.9604 -0.9618 -0.4892 0.0681 6.6469 ## ## Coefficients: ## Estimate Std. Error z value Pr(>|z|) ## (Intercept) 4.6651 0.1370 34.05 < 2e-16 *** ## factor(Tissue)Lung 0.4491 0.1688 2.66 0.00781 ** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## (Dispersion parameter for Negative Binomial(1.0345) family taken to be 1) ## ## Null deviance: 180.46 on 151 degrees of freedom ## Residual deviance: 173.75 on 150 degrees of freedom ## AIC: 1819 ## ## Number of Fisher Scoring iterations: 1 ## ## ## Theta: 1.034 ## Std. Err.: 0.106 ## ## 2 x log-likelihood: -1812.977 The p-value is significant (p = 0.00781), suggesting that ACE2 expression does differ between liver and lung. The coefficient estimate, 0.4491, indicates that RNA-seq counts for ACE2 are \\(0.45\\) transcripts higher in lung than in liver. "],["coronavirus-phylogenetics.html", "12 Coronavirus phylogenetics", " 12 Coronavirus phylogenetics In this lab, we’ll use Nextstrain to explore the evolution of SARS-CoV-2 and then build our own coronavirus phylogenies within R. 12.0.0.1 Learning objectives After completing this chapter, you’ll be able to: Interpret viral phylogenies and associated data on Nextstrain. Explain how incomplete sampling affects phylogenies. Describe how phylogenetic trees are built through neighbor joining. "],["phylogenetic-trees.html", "12.1 Phylogenetic trees", " 12.1 Phylogenetic trees Phylogenetic trees represent the evolutionary relationships between samples. When comparing genetic sequences, we construct trees based on shared mutations between sequences – with the caveat that sometimes the same mutation can arise independently on different lineages. Human vs. viral phylogenies Constructing a phylogeny for human sequences is complicated by recombination (as well as diploidy and sex chromosomes), which means that every non-recombined segment of the genome has its own phylogenetic history. Viral phylogenies are simpler to construct because they recombine less frequently than human chromosomes do. While the frequency of recombination varies by virus, ~3% of SARS-CoV-2 lineages show evidence of recombination (as opposed to 100% of human lineages, since recombination is an essential component of human meiosis). Similar to the human Y chromosome, viral genomes typically accumulate mutations without recombination to split up haplotypes. "],["nextstrain.html", "12.2 Nextstrain", " 12.2 Nextstrain We’ll be visualizing the evolutionary history of SARS-CoV-2 with a web application called Nextstrain, developed by Trevor Bedford and colleagues at the Fred Hutch Cancer Center. Reading a phylogenetic tree Nextstrain provides a guide on how to interpret their phylogenetic trees. The figure below shows a “transmission tree” of viruses, where every dot is individual who was infected. Some of these individuals infect others, and some are dead ends (no transmission). After a mutation (diamonds) occurs on a branch, any sample to the right of the mutation will also carry it. Fig. 1. The “true” tree of virus transmission through a population (source). "],["incomplete-sampling.html", "12.3 Incomplete sampling", " 12.3 Incomplete sampling The tree we just saw is the complete, “full” tree of transmission, but we are almost never able to sample all the individuals we need to reconstruct it. Incomplete sampling can result in inaccurate interpretations of a phylogenetic tree (ex: inferring fewer introductions of the virus from a source population into a new population). Fig. 2. Incomplete sampling complicates interpretations of a phylogeny (source). "],["tracking-sars-cov-2-with-phylogenetics.html", "12.4 Tracking SARS-CoV-2 with phylogenetics", " 12.4 Tracking SARS-CoV-2 with phylogenetics Go to the Nextstrain browser to explore the phylogeny of SARS-CoV-2 sequences. Note that you can use the PLAY button on the left sidebar to watch its progression over time. Hovering over a specific node tells you the ID of the virus that was sequenced. It also tells you the divergence, which is the number of mutations it carries with respect to the root of the tree. Fig. 3. SARS-CoV-2 phylogeny from Nextstrain (source). One example of the public health value of this phylogenetic analysis was the observation that the second reported case of novel coronavirus in Washington state (WA2) was genetically similar to the first reported case (WA1) six weeks earlier, suggesting ongoing community transmission. Click the tweet expand the full thread. (kevin_purcell?) Please feel free to try (click the menu Embed Tweet here) and let me know if it does not work. — Yihui Xie ((xieyihui?)) July 28, 2016 "],["sars-cov-2-mutation-landscape.html", "12.5 SARS-CoV-2 mutation landscape", " 12.5 SARS-CoV-2 mutation landscape The phylogeny page also has a “diversity” section, where it plots the number of mutations observed in different regions of the SARS-CoV-2 genome sequence. Fig. 4. Genomic distribution of mutations across SARS-CoV-2 strains (source). Does this plot imply that specific regions of the SARS-CoV-2 genome are more susceptible to mutation? No – this plot can be interpreted as showing where mutations persist in the SARS-CoV-2 genome, not where they occur. Although mutation occurrence is mostly random, the genomic distribution we see in this plot has been filtered by natural selection. Beneficial mutations are selected for, causing them to appear more frequently in pathogenically important regions like the spike protein (S). We sometimes see recurring independent mutations where the same amino acid is changed across different SARS-CoV-2 strains, which is extremely strong evidence of selection. "],["setup-8.html", "12.6 Setup", " 12.6 Setup In the rest of this module we’ll place SARS-CoV-2 on a phylogeny of 24 distantly related coronavirus sequences (SARS, MERS, etc.) from both human and animal hosts. 12.6.1 R packages We’ll use ape for phylogenetics, ggtree for plotting trees, and harrietr for data transformation. library(tidyverse) library(ape) library(ggtree) library(harrietr) "],["data-5.html", "12.7 Data", " 12.7 Data 12.7.0.1 Metadata The accessions dataframe contains the GenBank IDs and full names of the coronavirus sequences we’re using: accessions <- read.table("accessions.txt", header = TRUE, sep = "\\t") head(accessions) ## id name ## 1 DQ022305 DQ022305.2 Bat SARS coronavirus HKU3-1 ## 2 DQ071615 DQ071615.1 Bat SARS coronavirus Rp3 ## 3 DQ412043 DQ412043.1 Bat SARS coronavirus Rm1 ## 4 JX993988 JX993988.1 Bat coronavirus Cp/Yunnan2011 ## 5 FJ588686 FJ588686.1 Bat SARS CoV Rs672/2006 ## 6 JX993987 JX993987.1 Bat coronavirus Rp/Shaanxi2011 # make vectors of the GenBank IDs and full names # these will be used as input to functions later ids <- accessions$id names <- accessions$name The SARS-CoV-2 sequence we’re using is MT093631 (MT093631.2 Severe acute respiratory syndrome coronavirus 2 isolate SARS-CoV-2/human/CHN/WH-09/2020). 12.7.0.2 DNA sequences We’ve downloaded and aligned the genome sequences of these coronaviruses in the aligned.fa FASTA file. Click on the file to preview the sequence of the first coronavirus: >DQ022305 ----------------------------------------GTTAGGTTTTTACCTACCCAGGAAA--AGCCAACCAACC- TTGATCTCTTGTAGATCTGTTCTCTAAACGAACTTTAAAA------TCTGTGTGGCTGTCGCTCGGCTGCATGCCTAGCG CACCTACGCAGTATAAATATTAAT-AACTTTACTGTCGTTGACAAGAAACGAGTAACTCGTCCCTCTTCTGCAGACTGCT FASTA format .fa indicates a FASTA file, which is a text-based format for representing DNA (or protein) sequences. In a file that contains multiple sequences (like ours), the > character indicates the start of a new sequence and is usually followed by the sequence name. Why do the sequences have to be aligned? To construct a phylogeny, we compare how a site in the genome has changed in different coronavirus strains. Sequences need to be aligned so that we know we’re comparing the same site across sequences. "],["neighbor-joining-trees.html", "12.8 Neighbor joining trees", " 12.8 Neighbor joining trees One approach to building a phylogeny of sequences is neighbor joining, which clusters sequences based on their pairwise genetic distance. In this approach, we: Start with a star phylogeny that assumes all samples are equally related (Fig. 5A) Compute a pairwise distance matrix between sequences, and look for the pair of sequences that are most similar to each other We join these two sequences to form a new node (Fig. 5B) The distance matrix is re-computed and this process repeats until all nodes are joined (Fig. 5C) Fig. 5. Steps for constructing a neighbor joining tree (source). "],["computing-pairwise-distance.html", "12.9 Computing pairwise distance", " 12.9 Computing pairwise distance Read in the FASTA file of aligned sequences with the read.dna function from ape: dna <- read.dna("aligned.fa", format = "fasta", as.matrix = TRUE) We then compute the pairwise distance matrix: D <- dist.dna(dna, model = "TN93", as.matrix = TRUE) We can plot this matrix to visualize it: # use the "melt_dist" function from harrietr package to convert # the distance matrix to "long" format for ggplot D_melted <- rbind(melt_dist(D, order = ids), melt_dist(t(D), order = rev(ids))) # plot distance matrix ggplot(data = D_melted) + geom_tile(aes(x = iso1, y = iso2, fill = (dist + 1e-5))) + theme_classic() + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + scale_fill_viridis_c(name = "distance") + xlab("sample") + ylab("sample") Interpreting the distance matrix Most of these coronaviruses seem to be fairly similar – i.e., there’s no clear clustering of sequences – besides HQ166910, which looks genetically distinct from the other sequences. "],["building-a-phylogenetic-tree.html", "12.10 Building a phylogenetic tree", " 12.10 Building a phylogenetic tree Using the distance matrix, we can now: Build a neighbor joining tree using the nj() function Use HQ166910 as the outgroup to root the tree (with the root() function) Use the ladderize() function to re-orient the tree into a tidier format for plotting # build a neighbor joining tree tree <- nj(D) # manually "root" the tree by setting HQ166910 as an outgroup tree <- root(tree, which(ids == "HQ166910")) # rotate tree at nodes to make it look tidier (i.e., "ladderized") tree <- ladderize(tree) # plot the tree ggtree(tree) + theme_tree2() + geom_tiplab(label = names, size = 4) + xlim(0, 1.2) On the tree, we can see that the 2019-nCov sample (MT093631.2 Severe acute respiratory syndrome coronavirus 2) groups most closely with Bat coronavirus RaTG13. Do you think this similarity is sufficient to confirm a bat origin of SARS-CoV-2? Although the distance between SARS-CoV-2 and RaTG13 in the phylogeny looks small, it’s a large distance in phylogenetic space. Without sampling more deeply within intermediate strains between RaTG13 and SARS-CoV-2, we don’t know whether it passed through other mammalian species before being transmitted to humans. "],["assess-bootstrap-support.html", "12.11 Assess bootstrap support", " 12.11 Assess bootstrap support A useful tool for evaluating confidence in a phylogenetic tree (or any other metric) is bootstrapping. This statistical method is based on resampling data with replacement from the original dataset. In our case, we resample aligned sites (i.e., bases) from the original alignment, then build a new tree with the resampled data. By repeating this procedure many times, we can evaluate confidence in various parts of the original tree by asking how often the trees from resampled data contain these features. Run the code below to implement bootstrapping in the boot.phylo() function. The output is a vector of bootstrap support values, which we can overlay onto the tree. # set random seed set.seed(123) # bootstrap and build new trees to evaluate uncertainty myBoots <- boot.phylo(tree, dna, function(x) ladderize(root(nj(dist.dna(x, model = "TN93")), which(ids == "HQ166910"))), rooted = TRUE) ## Running bootstraps: 100 / 100 ## Calculating bootstrap values... done. # replace "NA" with zero in bootstrap results; do not label terminal nodes myBoots[is.na(myBoots)] <- 0 myBoots <- c(rep(NA, 25), myBoots) # re-plot tree with bootstrap values ggtree(tree, branch.length = "none") + theme_tree2() + geom_tiplab(label = names) + geom_label(aes(label = myBoots), size = 3) + xlim(0, 15) ## Warning: Removed 25 rows containing missing values (geom_label). "],["conclusion-10.html", "12.12 Conclusion", " 12.12 Conclusion In this module, we visualized evolutionary relationships between coronavirus strains using Nextstrain and by constructing our own phylogenies in R. We first explored Nextstrain, a browser that summarizes historical sequencing data from SARS-CoV-2 strains around the world. We observed independent recurrent mutations in pathogenically relevant regions of the SARS-CoV-2 genome, suggesting that such mutations confer a fitness benefit and are under positive selection. Using the sequences of other coronavirus strains from GenBank, we placed SARS-CoV-2 onto a neighbor joining phylogeny of closely related viruses. We used bootstrapping to provide confidence estimates for branches on our neighbor joining tree. "],["homework-10.html", "12.13 Homework", " 12.13 Homework 12.13.0.1 Learning Objectives Practice building and interpreting phylogenies in R 12.13.0.2 Assignment hw_accessions.txt and hw_aligned.fa provide the alignments and metadata for 24 human SARS-CoV-2 sequences, plus the bat RaTG13 coronavirus strain. Use this data to repeat the analysis we did in class (compute distance matrix, construct neighbor joining tree, perform bootstrapping for confidence values) to build a phylogeny of SARS-CoV-2 strains. You should use RaTG13 (accession: MN996532) as an outgroup. Solution Read in accession data: accessions <- read.table("hw_accessions.txt", sep = "\\t", header = TRUE) # make vectors of accessions IDs and full names ids <- accessions$id names <- accessions$name Construct distance matrix: # read fasta file dna <- read.dna("hw_aligned.fa", format = "fasta", as.matrix = TRUE) # compute pairwise distance matrix D <- dist.dna(dna, model = "TN93", as.matrix = TRUE) Build neighbor joining tree: # make the tree tree <- nj(D) # manually root tree at RaTG13 coronavirus tree <- root(tree, which(ids == "MN996532")) # ladderize tree tree <- ladderize(tree) Bootstrap to determine tree uncertainty: set.seed(123) myBoots <- boot.phylo(tree, dna, function(x) ladderize(root(nj(dist.dna(x, model = "TN93")), which(ids == "MN996532"))), rooted = TRUE) ## Running bootstraps: 100 / 100 ## Calculating bootstrap values... done. # replace "NA" with zero myBoots[is.na(myBoots)] <- 0 Plot the bootstrapped tree: ggtree(tree, branch.length = "none") + theme_tree2() + geom_tiplab(label = names) + geom_nodelab(label = myBoots, geom = "label", fill = "#deebf7") + xlim(0, 25) "],["authors.html", "Authors", " Authors     Credits Names Pedagogy Instructor Rajiv McCoy Content Author Stephanie Yan Content Author Kate Weaver Website Template Jeff Leek & The Johns Hopkins Data Science Lab Design Inspiration Ali Madooei & JHU Data Structures Funding JHU Center for Educational Resources Techology Fellowship Grant   ## ─ Session info ─────────────────────────────────────────────────────────────── ## setting value ## version R version 4.0.2 (2020-06-22) ## os Ubuntu 20.04.5 LTS ## system x86_64, linux-gnu ## ui X11 ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz Etc/UTC ## date 2024-02-21 ## ## ─ Packages ─────────────────────────────────────────────────────────────────── ## package * version date lib source ## admixr * 0.9.1 2020-07-03 [1] RSPM (R 4.0.2) ## ape * 5.4-1 2020-08-13 [1] RSPM (R 4.0.2) ## aplot 0.0.6 2020-09-03 [1] RSPM (R 4.0.3) ## assertthat 0.2.1 2019-03-21 [1] RSPM (R 4.0.5) ## backports 1.1.10 2020-09-15 [1] RSPM (R 4.0.2) ## BiocManager 1.30.10 2019-11-16 [1] RSPM (R 4.0.0) ## blob 1.2.1 2020-01-20 [1] RSPM (R 4.0.3) ## bookdown 0.24 2023-03-28 [1] Github (rstudio/bookdown@88bc4ea) ## broom 0.7.1 2020-10-02 [1] RSPM (R 4.0.2) ## bslib 0.4.2 2022-12-16 [1] CRAN (R 4.0.2) ## cachem 1.0.7 2023-02-24 [1] CRAN (R 4.0.2) ## calibrate 1.7.7 2020-06-19 [1] RSPM (R 4.0.1) ## callr 3.5.0 2020-10-08 [1] RSPM (R 4.0.2) ## cellranger 1.1.0 2016-07-27 [1] RSPM (R 4.0.3) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.0.2) ## cluster 2.1.0 2019-06-19 [2] CRAN (R 4.0.2) ## colorspace 1.4-1 2019-03-18 [1] RSPM (R 4.0.0) ## crayon 1.3.4 2017-09-16 [1] RSPM (R 4.0.0) ## DBI 1.1.0 2019-12-15 [1] RSPM (R 4.0.0) ## dbplyr 1.4.4 2020-05-27 [1] RSPM (R 4.0.0) ## desc 1.2.0 2018-05-01 [1] RSPM (R 4.0.3) ## devtools 2.3.2 2020-09-18 [1] RSPM (R 4.0.3) ## digest 0.6.25 2020-02-23 [1] RSPM (R 4.0.0) ## dplyr * 1.0.2 2020-08-18 [1] RSPM (R 4.0.2) ## ellipsis 0.3.1 2020-05-15 [1] RSPM (R 4.0.3) ## evaluate 0.20 2023-01-17 [1] CRAN (R 4.0.2) ## fansi 0.4.1 2020-01-08 [1] RSPM (R 4.0.0) ## farver 2.0.3 2020-01-16 [1] RSPM (R 4.0.3) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.0.2) ## forcats * 0.5.0 2020-03-01 [1] RSPM (R 4.0.0) ## fs 1.5.0 2020-07-31 [1] RSPM (R 4.0.3) ## generics 0.0.2 2018-11-29 [1] RSPM (R 4.0.0) ## ggplot2 * 3.3.2 2020-06-19 [1] RSPM (R 4.0.1) ## ggtree * 2.4.2 2021-04-26 [1] Bioconductor ## glue 1.4.2 2020-08-27 [1] RSPM (R 4.0.5) ## gtable 0.3.0 2019-03-25 [1] RSPM (R 4.0.3) ## harrietr * 0.2.3 2017-12-01 [1] RSPM (R 4.0.2) ## haven 2.3.1 2020-06-01 [1] RSPM (R 4.0.2) ## highr 0.8 2019-03-20 [1] RSPM (R 4.0.3) ## hms 0.5.3 2020-01-08 [1] RSPM (R 4.0.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.0.2) ## httr 1.4.2 2020-07-20 [1] RSPM (R 4.0.3) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.0.2) ## jsonlite 1.7.1 2020-09-07 [1] RSPM (R 4.0.2) ## knitr 1.33 2023-03-28 [1] Github (yihui/knitr@a1052d1) ## labeling 0.3 2014-08-23 [1] RSPM (R 4.0.0) ## lattice 0.20-41 2020-04-02 [2] CRAN (R 4.0.2) ## lazyeval 0.2.2 2019-03-15 [1] RSPM (R 4.0.3) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.0.2) ## lubridate 1.7.9 2020-06-08 [1] RSPM (R 4.0.2) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.0.2) ## MASS * 7.3-51.6 2020-04-26 [2] CRAN (R 4.0.2) ## Matrix 1.2-18 2019-11-27 [2] CRAN (R 4.0.2) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.0.2) ## memuse 4.1-0 2020-02-17 [1] RSPM (R 4.0.0) ## mgcv 1.8-31 2019-11-09 [2] CRAN (R 4.0.2) ## modelr 0.1.8 2020-05-19 [1] RSPM (R 4.0.3) ## munsell 0.5.0 2018-06-12 [1] RSPM (R 4.0.3) ## nlme 3.1-148 2020-05-24 [2] CRAN (R 4.0.2) ## ottrpal 1.0.1 2023-03-28 [1] Github (jhudsl/ottrpal@151e412) ## patchwork 1.0.1 2020-06-22 [1] RSPM (R 4.0.2) ## permute 0.9-5 2019-03-12 [1] RSPM (R 4.0.3) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.0.2) ## pinfsc50 1.2.0 2020-06-03 [1] RSPM (R 4.0.0) ## pkgbuild 1.1.0 2020-07-13 [1] RSPM (R 4.0.2) ## pkgconfig 2.0.3 2019-09-22 [1] RSPM (R 4.0.3) ## pkgload 1.1.0 2020-05-29 [1] RSPM (R 4.0.3) ## prettyunits 1.1.1 2020-01-24 [1] RSPM (R 4.0.3) ## processx 3.4.4 2020-09-03 [1] RSPM (R 4.0.2) ## ps 1.4.0 2020-10-07 [1] RSPM (R 4.0.2) ## purrr * 0.3.4 2020-04-17 [1] RSPM (R 4.0.5) ## qqman * 0.1.4 2017-03-16 [1] RSPM (R 4.0.0) ## R6 2.4.1 2019-11-12 [1] RSPM (R 4.0.0) ## Rcpp 1.0.10 2023-01-22 [1] CRAN (R 4.0.2) ## readr * 1.4.0 2020-10-05 [1] RSPM (R 4.0.2) ## readxl 1.3.1 2019-03-13 [1] RSPM (R 4.0.2) ## remotes 2.2.0 2020-07-21 [1] RSPM (R 4.0.3) ## reprex 0.3.0 2019-05-16 [1] RSPM (R 4.0.0) ## rlang 1.1.0 2023-03-14 [1] CRAN (R 4.0.2) ## rmarkdown 2.10 2023-03-28 [1] Github (rstudio/rmarkdown@02d3c25) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.0.2) ## rstudioapi 0.11 2020-02-07 [1] RSPM (R 4.0.0) ## rvcheck 0.1.8 2020-03-01 [1] RSPM (R 4.0.0) ## rvest 1.0.1 2023-03-28 [1] Github (tidyverse/rvest@4fe39fb) ## sass 0.4.5 2023-01-24 [1] CRAN (R 4.0.2) ## scales 1.1.1 2020-05-11 [1] RSPM (R 4.0.3) ## sessioninfo 1.1.1 2018-11-05 [1] RSPM (R 4.0.3) ## stringi 1.5.3 2020-09-09 [1] RSPM (R 4.0.3) ## stringr * 1.4.0 2019-02-10 [1] RSPM (R 4.0.3) ## testthat 3.0.1 2023-03-28 [1] Github (R-lib/testthat@e99155a) ## tibble * 3.2.1 2023-03-20 [1] CRAN (R 4.0.2) ## tidyr * 1.1.2 2020-08-27 [1] RSPM (R 4.0.2) ## tidyselect 1.1.0 2020-05-11 [1] RSPM (R 4.0.3) ## tidytree 0.3.3 2020-04-02 [1] RSPM (R 4.0.3) ## tidyverse * 1.3.0 2019-11-21 [1] RSPM (R 4.0.3) ## treeio 1.14.4 2021-04-26 [1] Bioconductor ## usethis 1.6.3 2020-09-17 [1] RSPM (R 4.0.2) ## utf8 1.1.4 2018-05-24 [1] RSPM (R 4.0.3) ## vcfR * 1.12.0 2020-09-01 [1] RSPM (R 4.0.2) ## vctrs 0.6.1 2023-03-22 [1] CRAN (R 4.0.2) ## vegan 2.5-6 2019-09-01 [1] RSPM (R 4.0.0) ## viridisLite 0.3.0 2018-02-01 [1] RSPM (R 4.0.3) ## withr 2.3.0 2020-09-22 [1] RSPM (R 4.0.2) ## xfun 0.26 2023-03-28 [1] Github (yihui/xfun@74c2a66) ## xml2 1.3.2 2020-04-23 [1] RSPM (R 4.0.3) ## yaml 2.2.1 2020-02-01 [1] RSPM (R 4.0.3) ## ## [1] /usr/local/lib/R/site-library ## [2] /usr/local/lib/R/library "],["404.html", "Page not found", " Page not found The page you requested cannot be found (perhaps it was moved or renamed). You may want to try searching to find the page's new location, or use the table of contents to find the page you are looking for. "]]

q@_e4bKtk!Y<89 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%0DQF@p@11}OUI=tMN`FsN>v16P|JoVYyaKK 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 diff --git a/docs/index.html b/docs/index.html index 7ed63453..7a4a29da 100644 --- a/docs/index.html +++ b/docs/index.html @@ -422,9 +422,6 @@