<jupyter_start><jupyter_text>Using SNP mismatches to delimit multilocus lineages (MLLs)Individuals belonging to the same clonal lineages should show higher-than-expected identity across loci. This is usually explored by plotting a histogram of pairwise distances and looking for a peak with the lowest distances between individuals, and a saddle point, giving us a threshold distance to distinguish intraclonal and interclonal comparisons.Here we used hamming distance (i.e. any mismatch in genotype), divided by total number of sites compared for a given pair, as a distance measure to make the histogram.Let's start by preparing a workspace: setting default plot options and loading the [magrittr library](https://cran.r-project.org/web/packages/magrittr/vignettes/magrittr.html) for easier manipulation of data with *pipes* (`%>%` and others).<jupyter_code>options(repr.plot.width=7, repr.plot.height=5, jupyter.plot_scale = 1)

library(magrittr)<jupyter_output><empty_output><jupyter_text>Load a table produced by `pairwise_mismatches.r` script with additional information on species and hybrid biotypes included:<jupyter_code>distances <- read.csv("LOH_dist.csv")[,-1] # [,-1] excludes rownames exported by write.csv()
head(distances)<jupyter_output><empty_output><jupyter_text>The two `bio` columns describe species or hybrid type of samples in the two `anim` columns:- anim1 ~ bio1- anim2 ~ bio2Species and hybrid biotypes in the dataset:<jupyter_code>c(distances$bio1, distances$bio2) %>% unique<jupyter_output><empty_output><jupyter_text>PlotsNow we can plot histograms using the `p_mismatch` column, i.e. the proportion of mismatches in total positions considered for each pair:<jupyter_code>hist(distances$p_mismatch, main="Proportion of mismatches", breaks=150, xlab="mismatch / total")<jupyter_output><empty_output><jupyter_text>Let's deconstruct the above histogram by subsetting the data to several categories and plotting them.The plots below show distances (in terms of proportion of mismatches between genotypes) for these groups:- **TT** = within *C. taenia*- **EE** = within *C. elongatoides*- **TT/EE** = between *C. taenia* and *C. elongatoides*- **Hybrids** = all asexual hybrids<jupyter_code>par(mfrow=c(1,2))
distances %>% subset(bio1=="TT" & bio2=="TT") %$% hist(p_mismatch, breaks=20, main="TT")
distances %>% subset(bio1=="EE" & bio2=="EE") %$% hist(p_mismatch, breaks=20, main="EE")
distances %>% subset((bio1=="EE" & bio2=="TT") | (bio1=="TT" & bio2=="EE")) %$% hist(p_mismatch, breaks=30, main="EE/TT")
distances %>% subset(grepl("ET|EN",bio1) & grepl("ET|EN",bio2)) %$% hist(p_mismatch, breaks=30, main="Hybrids")<jupyter_output><empty_output><jupyter_text>We can see that distances **within sexual species** (here TT or EE) have a peak around 0.1, with *C. taenia* (TT) showing smaller distances than *C. elongatoides*, which is expected, given its smaller effective population size.The right-most peak with the largest distances corresponds to comparisons **between sexual species** EE and TT.> Note that we don't show all combinations here - there is also *C. tanaitica*, or comparisons between sexuals and asexual hybrids. But we are interested in lineages within asexuals, so we will leave these illustrative examples as they are now.Lastly, the **asexual hybrids** show several peaks. Let's zoom in on their histogram:<jupyter_code>distances %>% subset(grepl("ET|EN",bio1) & grepl("ET|EN",bio2)) %$% 
    hist(p_mismatch, breaks=50, main="Asexual hybrids")<jupyter_output><empty_output><jupyter_text>Let's save this subset of data into a new object `hybs` for easier access:<jupyter_code>hybs <- distances %>% subset(grepl("ET|EN",bio1) & grepl("ET|EN",bio2))

# check present genomotypes
c(hybs$bio1, hybs$bio2) %>% unique<jupyter_output><empty_output><jupyter_text>Exploring peaksFirst, let's see which pairwise comparisons contribute to the right-most peaks, above the value 0.15:<jupyter_code>hybs %>% 
    subset(p_mismatch>0.15) %$% 
    paste(bio1,bio2, sep="-") %>% unique<jupyter_output><empty_output><jupyter_text>As we can see, these large distances mostly correspond to combinations of hybrids with different genomic compositions. In particular, we always see an *elongatoides-taenia* hybrid (ET / EET / ETT) paired with an *elongatoides-tanaitica* hybrid (EN / EEN).Next, we can have a look at the middle peak, at distances between 0.06 & 0.15:<jupyter_code>hybs %>% 
    subset(p_mismatch<0.15 & p_mismatch>0.06) %$% 
    paste(bio1,bio2, sep="-") %>% unique<jupyter_output><empty_output><jupyter_text>Here the combinations are between different genomotypes of hybrids, but always within one of the two main hybrid types: either *elongatoides-taenia* hybrids (E & T genomes) or *elongatoides-tanaitica* hybrids (E & N genomes).Lastly, let's see the pairs contributing to the small left-most peak, where distances are below 0.06:<jupyter_code>hybs %>% 
    subset(p_mismatch<0.06) %$% 
    paste(bio1,bio2, sep="-") %>% unique<jupyter_output><empty_output><jupyter_text>These distances *nearly always* correspond to pairs from within the same genomotypes, except the last two pairs: ET-ETT & ETT-ET. If we look up the samples involved, we see they are young hybrids from the same sampling site in Poland - HZ0701:<jupyter_code>hybs %>% 
    subset(((bio1=="ET" & bio2=="ETT") | (bio1=="ETT" & bio2=="ET")) & p_mismatch<0.06)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11896392229417206, 'fraction_numerical': 0.01572617946345976, 'mean_word_length': 6.275908479138627, 'pattern_counts': {'":': 0, '<': 50, '<?xml version=': 0, '>': 64, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '618665', 'license': 'MIT', 'n_tokens_mistral': 1838, 'n_tokens_neox': 1683, 'n_words': 556, 'path': 'mlls_appendix.ipynb', 'repo_name': 'cobitislab/LOH-scripts', 'size': '5405'}