Skip to content

Instantly share code, notes, and snippets.

@hughjonesd
Last active October 11, 2025 21:15
Show Gist options
  • Select an option

  • Save hughjonesd/6b1f1e9f4243c2a322965e854cf856f4 to your computer and use it in GitHub Desktop.

Select an option

Save hughjonesd/6b1f1e9f4243c2a322965e854cf856f4 to your computer and use it in GitHub Desktop.
Ancestry versus ethnicity simulation
pop <- data.frame(
group = rep(1:2, each = 1000),
allele = rep(rep(c("H", "L"), times = c(250, 750)), 2)
)
pop$ancestry <- paste0(pop$allele, pop$group)
pop$elite <- pop$group == 1 & pop$allele == "H"
# for simplicity, people can have multiple marriages (and may marry themselves)
pop$partner <- integer(2000)
pop$partner[pop$elite] <- sample(which(pop$elite))
pop$partner[! pop$elite] <- sample(which(! pop$elite))
pop$partner_ancestry <- pop$ancestry[pop$partner]
pop$partner_group <- pop$group[pop$partner]
pop$child_ancestry <- ifelse(runif(2000) < 0.5, pop$ancestry, pop$partner_ancestry)
# all mixed marriages count as group 2
pop$child_group <- ifelse(pop$group == pop$partner_group, pop$group, 2)
pop$child_allele <- ifelse(grepl("H", pop$child_ancestry), "H", "L")
pop$child_ancestry_group <- ifelse(grepl("1", pop$child_ancestry), 1, 2)
# Results:
round(proportions(table(Group = pop$child_group, "Allele (%)" = pop$child_allele), 1), 3) * 100
round(proportions(table(Group = pop$child_group, Ancestry = pop$child_ancestry), 1), 3) * 100
ancestry_group_2_tbl <- with(pop[pop$child_group == 2,],
table(Ancestry = child_ancestry_group, `Allele (%)` = child_allele)
)
round(proportions(ancestry_group_2_tbl, 1), 3) * 100
ancestry_all_tbl <- with(pop,
table(Ancestry = child_ancestry_group, `Allele (%)` = child_allele)
)
round(proportions(ancestry_all_tbl, 1), 3) * 100
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment