Consider an m x n genotype matrix of m haploid samples and n SNPs where each value is an allele encoded by an integer (0,1,2,3).

Is there a good/standard way to encode the alleles in order to perform a PCA on this matrix to investigate population structure ?

I have seen this with matrices of diploid samples where each SNP is encoded as 0/1/2 to represent the number of non-reference allele, but is there a way to consider more than 2 alleles ?

e.g. difference between alleles 1 and 3 should be equal to difference between alleles 1 and 2


2 Answers 2


You can make a 'dummy variable' for each allele. That means that you don't have info per SNP, but for SNPs with more alleles, the allele is present (1) or not (0).


I recommend the Hamming distance and doing a multidimensional scaling (a procedure similar to PCA but for distances), that way you don't create new variables for the same position.

The distance function can be defined as

hamming_dist <- function(x, y) {
    if (x != y) {
    } else {

Or you can use a package:

H <- hamming.distance(as.matrix(X))

Or as you yourself pointed other implementations.

You can use them to calculate the distance between all samples and then use it for the multidimensional analysis (cmdscale in R)

  • $\begingroup$ Although I accepted the other answer as it addresses PCA directly, this is a really good alternative! However, the implementation of the Hamming distance in e1071 relies on a nested loop, making it unusable on large SNP matrices. This blog provides a (much) more efficient implementation (in R as well) using matrix multiplication: johanndejong.wordpress.com/2015/10/02/… $\endgroup$
    – cmdoret
    Commented Apr 11, 2018 at 11:41
  • $\begingroup$ I add your finding to the answer (the comment might get deleted). Glad you find it useful. $\endgroup$
    – llrs
    Commented Apr 11, 2018 at 14:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.