How to run qpAdm: in R, on the command line, or in your browser
Three ways to run a qpAdm model: ADMIXTOOLS 2 in R, classic ADMIXTOOLS with a parameter file, or Nexju in the browser with the AADR ready and nothing to install.
Updated 7 min read
You can run qpAdm in three ways. Use the qpadm() function of ADMIXTOOLS 2 in R, use the classic ADMIXTOOLS qpAdm program with a parameter file, or use Nexju in your browser, where the Allen Ancient DNA Resource is already loaded and there is nothing to install. All three run the same test: is the target a mixture of the sources, as seen from the right populations, and in what proportions.
This guide shows each way with a working example, then what to check before you trust a result. If you are new to the method, read What is qpAdm? first.
What every qpAdm run needs
Whichever way you run it, a qpAdm model has the same parts:
Genotype data: the Allen Ancient DNA Resource (AADR) or another dataset in EIGENSTRAT (
.geno,.snp,.ind) or PLINK format. To model yourself, your raw DNA file must be merged into it.A target: the population, or the one genome, you want to explain.
Sources (the "left" populations): two or more candidate ancestries.
Right populations: outgroups that relate to the sources in different ways. You need more right populations than sources, and at least one more. A 2-source model needs at least 3. See Choosing right populations.
The examples below use one model: a target explained by western hunter-gatherers (Luxembourg_Loschbour_Mesolithic), Anatolian farmers (Turkey_N) and Yamnaya steppe herders (Russia_Samara_EBA_Yamnaya), against six right populations. Replace YourTarget with a population label from your dataset.
Run qpAdm in R with ADMIXTOOLS 2
ADMIXTOOLS 2 is an R package from Robert Maier and Nick Patterson. It computes f2-statistics once, stores them on disk, and fits models from them in seconds. Install it from GitHub:
install.packages("devtools")
devtools::install_github("uqrmaie1/admixtools")Then extract f2-statistics for every population of the model, and fit it:
library(admixtools)
prefix <- "v66.1240K" # the .geno/.snp/.ind files, without extension
target <- "YourTarget"
left <- c("Luxembourg_Loschbour_Mesolithic", "Turkey_N", "Russia_Samara_EBA_Yamnaya")
right <- c("Mbuti", "Russia_UstIshim_IUP", "Russia_Malta_UP",
"Iran_GanjDareh_N", "Israel_Natufian", "Han")
extract_f2(prefix, outdir = "f2", pops = c(target, left, right), maxmiss = 0)
f2_blocks <- f2_from_precomp("f2")
fit <- qpadm(f2_blocks, left, right, target)
fit$weights # ancestry proportions, with standard errors and z-scores
fit$popdrop # the p-value of the full model and of each nested modelfit$weights has one row per source: its weight, its standard error se and its z. fit$popdrop lists the full model and every model with sources dropped, each with its chi-squared, degrees of freedom, p and a feasible flag (all weights between 0 and 1). The first row is the model you asked for.
With low-coverage ancient genomes, maxmiss = 0 can leave too few SNPs. You can then fit directly from the genotype files with qpadm(prefix, left, right, target, allsnps = TRUE), which uses every SNP each f4-statistic can use. It keeps more data, but the statistics no longer share one SNP set, so state it when you report the result.
Run qpAdm with classic ADMIXTOOLS
Classic ADMIXTOOLS is the original C package from the Reich laboratory. You compile it, then describe a run in a parameter file. List the target and sources in left.txt, target first:
YourTarget
Luxembourg_Loschbour_Mesolithic
Turkey_N
Russia_Samara_EBA_YamnayaList the right populations in right.txt, one per line, with the base population first (usually Mbuti). Then write parqpAdm:
genotypename: v66.1240K.geno
snpname: v66.1240K.snp
indivname: v66.1240K.ind
popleft: left.txt
popright: right.txt
details: YES
allsnps: YESRun it with qpAdm -p parqpAdm > qpAdm.log. The log prints the weights with their standard errors, the tail probability of the full model (its p-value) and the same "popdrop" table of nested models. It reads the whole genotype file on every run, so a rotation of many models is slow, and you script it yourself.
Run qpAdm in your browser with Nexju
Nexju runs qpAdm on the AADR (release v66, 1240K and Human Origins) on its servers. You choose populations from lists, not label files, and your own DNA is merged for you. Single qpAdm models and rotations are on the free plan.
1. Build the model
Sign in, open Models and choose New model.
Under Sources, choose Add sources and pick two or more populations. Each one shows how many genomes it holds; click it to see the genomes behind the label.
Under Right groups, add your outgroups, or add Nexju's suggested panel. The suggestions start with deep references (
Mbuti,Russia_UstIshim_IUP,Russia_Malta_UP), then add one population for each ancestry your sources descend from, and only ancient ones older than your youngest source.Choose Create model. Nexju will not create a model with too few right groups, and it names the problem.
The Parameters… button holds the allsnps setting. Leave it at NO unless the run reports too few SNPs.
2. Add a target and run
On the model's page, choose Run in workflow….
Choose Add target or DNA and pick a population, or a DNA file you uploaded.
Choose Run workflow. A qpAdm fit usually finishes in seconds.
3. Read the result
Each run shows the model's p-value, each source's weight with its standard error, and a verdict:
Plausible: p is 0.01 or more and every weight is between 0 and 1. The data do not reject the model.
Rejected: p is below 0.01. The sources cannot explain the target from these right populations.
Infeasible: a weight is below 0 or above 1, whatever the p-value. Usually a source is wrong or missing.
How to read qpAdm results explains p-values, weights and standard errors in detail. A run can be shared with a link, so others see the same numbers without an account.
4. Test the model before you trust it
One plausible model is not proof. Nexju has checks for the questions a reviewer asks:
Rotation (every plan): swap sources in and out, one slot at a time or every combination, and see which source sets pass for the same target.
Competing models (Pro): on a model's page, pick 2 to 6 completed fits of one target and test them against each other.
Right-panel sensitivity (Pro): refit with each right population left out, to see whether one outgroup carries the result.
Add a source (Pro): test whether a model improves with one more source.
Run qpAdm on your own DNA
To model your own genome in R or ADMIXTOOLS, you convert your raw data file, keep the SNPs it shares with the reference, and merge it into the EIGENSTRAT files yourself. Nexju does this when you upload:
Raw data files: 23andMe, AncestryDNA, MyHeritage, FTDNA, LivingDNA or tellmeGen exports, as
.txt,.csv,.zipor.gz. The free plan holds 5 files.Whole genomes (Max): a BAM or CRAM aligned to GRCh37/hg19, added by its link. Nexju calls your genotypes at the reference SNPs.
Your file is then a target like any population: choose it under Add target or DNA. A single consumer genome has fewer SNPs than a population, so expect larger standard errors. Raw DNA and ancient DNA explains what a consumer test can and cannot show. Nexju never shares your DNA, and you can delete a file at any time.
Run qpAdm from Claude or ChatGPT
On the Max plan, an AI assistant can run qpAdm for you through the Nexju MCP server. You describe the question in plain words; the assistant searches AADR populations, builds the models, runs them (up to 500 in one batch, or a rotation) and reads the results back, and every run appears in your Nexju history. Your raw DNA never passes through the assistant: you upload on the website, and the assistant refers to the file by its ID.
Which way to choose
ADMIXTOOLS 2 in R if you write R, need full control of every option, and can download and merge the AADR yourself.
Classic ADMIXTOOLS if you must reproduce a published pipeline exactly as it was run.
Nexju if you want to start modeling now, model your own consumer DNA without a merge pipeline, run rotations and robustness checks from a page, or let an AI assistant do the runs.
Published qpAdm studies use all three kinds of tools. The method is the same; what differs is how much setup you do before the first model.
Common problems
Too few SNPs. Low-coverage ancient genomes share few SNPs with every other population of the model. Nexju reports that "the populations share too few SNPs to estimate standard errors by block jackknife". Drop low-coverage populations or samples, or turn on
allsnps.Every model is rejected. A source may be too distant from the real ancestor, or an ancestry is missing. Try a source closer in time and place, or add one.
A negative weight. The model is infeasible. Two sources may be too similar for the right populations to tell apart: add a right population related to one of them, or remove one source.
A result changes with one outgroup. Check right-panel sensitivity. A model that holds only for one right panel is weak evidence.
References
Patterson N. et al. 2012. Ancient admixture in human history. Genetics 192. doi:10.1534/genetics.112.145037
Haak W. et al. 2015. Massive migration from the steppe was a source for Indo-European languages in Europe. Nature 522. doi:10.1038/nature14317
Harney É. et al. 2021. Assessing the performance of qpAdm: a statistical tool for studying population admixture. Genetics 217. doi:10.1093/genetics/iyaa045
Maier R. et al. 2023. On the limits of fitting complex models of population history to f-statistics. eLife 12. doi:10.7554/eLife.85492
Mallick S. et al. 2024. The Allen Ancient DNA Resource (AADR): a curated compendium of ancient human genomes. Scientific Data 11. doi:10.1038/s41597-024-03031-7