Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-11T11:41:14.213Z
Answers.Text: 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/
Answers.UserDisplayName: cmdoret
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-11T14:54:23.787Z
Answers.Text: I add your finding to the answer (the comment might get deleted). Glad you find it useful.
Answers.UserDisplayName: llrs
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-11T09:59:17.500Z
Answers.LastActivityDate: 2018-04-11T14:54:58.677Z
Answers.LastEditDate: 2018-04-11T14:54:58.677Z
Answers.UserDisplayName: llrs
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-09T13:01:49.597Z
Answers.LastActivityDate: 2018-04-09T13:01:49.597Z
Answers.UserDisplayName: benn
Body: <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>
  
Tags: <snp><pca>
Title: PCA on genotype matrix with multiple alleles
ThreadText: # 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](https://en.wikipedia.org/wiki/Hamming_distance) and doing a [multidimensional scaling](https://en.wikipedia.org/wiki/Multidimensional_scaling) (a procedure [similar](https://stats.stackexchange.com/q/14002/105234) 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](https://johanndejong.wordpress.com/2015/10/02/faster-hamming-distance-in-r-2/).
  
  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.  
  
  ---
  
  