<p>I recommend the <a href="https://en.wikipedia.org/wiki/Hamming_distance" rel="nofollow noreferrer">Hamming distance</a> and doing a <a href="https://en.wikipedia.org/wiki/Multidimensional_scaling" rel="nofollow noreferrer">multidimensional scaling</a>  (a procedure <a href="https://stats.stackexchange.com/q/14002/105234">similar</a> to PCA but for distances), that way you don't create new variables for the same position.</p>

<p>The distance function can be defined as</p>

<pre><code>hamming_dist &lt;- function(x, y) {
    if (x != y) {
        1
    } else {
        0
    }
</code></pre>

<p>Or you can use a package:</p>

<pre><code>library(e1071)
H &lt;- hamming.distance(as.matrix(X))
</code></pre>

<p>Or as you yourself pointed <a href="https://johanndejong.wordpress.com/2015/10/02/faster-hamming-distance-in-r-2/" rel="nofollow noreferrer">other implementations</a>.</p>

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

<pre><code>plot(cmdscale(H))
</code></pre>

CC BY-SA 3.0
2018-04-11T11:41:14.213Z
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: https://johanndejong.wordpress.com/2015/10/02/faster-hamming-distance-in-r-2/
cmdoret
CC BY-SA 3.0
2018-04-11T14:54:23.787Z
I add your finding to the answer (the comment might get deleted). Glad you find it useful.
llrs
CC BY-SA 3.0
2018-04-11T09:59:17.500Z
2018-04-11T14:54:58.677Z
2018-04-11T14:54:58.677Z
llrs
<p>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).</p>

CC BY-SA 3.0
2018-04-09T13:01:49.597Z
2018-04-09T13:01:49.597Z
benn
<p>Consider an <em>m x n</em> genotype matrix of <em>m</em> haploid samples and <em>n</em> SNPs where each value is an allele encoded by an integer (0,1,2,3). </p>

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

<p>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 ?</p>

<p>e.g. difference between alleles 1 and 3 should be equal to difference between alleles 1 and 2</p>

<snp><pca>
PCA on genotype matrix with multiple alleles
# PCA on genotype matrix with multiple alleles

(Asked by: username_0 on 2018-04-09)

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

**Tags:** snp, pca

---

## 2 answers

### Answer by username_2 on 2018-04-09. Score: 3 | Accepted answer

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).


---

### Answer by username_1 on 2018-04-11. Score: 2

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) {
        1
    } else {
        0
    }

Or you can use a package:
library(e1071)
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)
plot(cmdscale(H))

> **Comments:**
> **username_0**: 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: https://johanndejong.wordpress.com/2015/10/02/faster-hamming-distance-in-r-2/  
> **username_1**: I add your finding to the answer (the comment might get deleted). Glad you find it useful.  

---

