R/dist.genpop.R

Defines functions dist.genpop

Documented in dist.genpop

###################################
#
# Distances functions
# based on old ade4 'dist.genet'
# by Daniel Chessel
#
# Thibaut Jombart
# t.jombart@imperial.ac.uk
###################################



############################
# S3 method dist for genpop
############################
dist.genpop <- function(x, method = 1, diag = FALSE, upper = FALSE) {

  if(!is.genpop(x)) stop("x is not a valid genpop object")

  ## haploidy kludge (have to get rid of that later)
  if(x@ploidy==as.integer(1)){
  x@tab <- x@tab * 2
  x@ploidy <- as.integer(2)
  }


  ## check marker type
  checkType(x)


  METHODS = c("Nei","Edwards","Reynolds","Rodgers","Provesti")
  if (all((1:5)!=method)) {
    cat("1 = Nei 1972\n")
    cat("2 = Edwards 1971\n")
    cat("3 = Reynolds, Weir and Coockerman 1983\n")
    cat("4 = Rodgers 1972\n")
    cat("5 = Provesti 1975\n")
    cat("Select an integer (1-5): ")
    method <- as.integer(readLines(con = getOption('adegenet.testcon'), n = 1))
  }
  if (all((1:5)!=method)) (stop ("Non convenient method number"))

  nloc <- length(levels(x@loc.fac))
  loc.fac <- x@loc.fac
  X <- makefreq(x,missing="mean",quiet=TRUE)
  # X is a matrix of allelic frequencies
  nlig <- nrow(X)

  if (method == 1) { # Nei
    d <- X%*%t(X)
    vec <- sqrt(diag(d))
    d <- d/vec[col(d)]
    d <- d/vec[row(d)]
    d <- -log(d)
    d <- as.dist(d)
  } else if (method == 2) { # Edward's (angular)
        X <- sqrt(X)
        d <- X%*%t(X)
        d <- 1-d/nloc
        diag(d) <- 0
        d <- sqrt(d)
        d <- as.dist(d)
    } else if (method == 3) { # Coancestrality coef (Reynold's)
       denomi <- X%*%t(X)
       vec <- apply(X,1,function(x) sum(x*x))
       d <- -2*denomi + vec[col(denomi)] + vec[row(denomi)]
       diag(d) <- 0
       denomi <- 2*nloc - 2*denomi
       diag(denomi) <- 1
       d <- d/denomi
       d <- sqrt(d)
       d <- as.dist(d)
    } else if (method == 4) { # Rogers' distance
      # kX is a list of K=nloc matrices
      kX <- lapply(split(X,loc.fac[col(X)]),matrix,nrow=nlig)
      dcano <- function(mat) {
        daux <- mat%*%t(mat)
        vec <- diag(daux)
        daux <- -2*daux + vec[col(daux)] + vec[row(daux)]
        diag(daux) <- 0
        daux <- sqrt(.5*daux)
        return(daux)
      }

      d <- matrix(0,nlig,nlig)
      for(i in 1:length(kX)) {
        d <- d + dcano(kX[[i]])
      }
      d <- d/length(kX)
      d <- as.dist(d)
    } else if (method ==5) { # Provesti (absolute genetic distance)
      w0 <- 1:(nlig-1)
      loca <- function(k) {
        w1 <- (k+1):nlig
        resloc <- unlist(lapply(w1, function(x) sum(abs(X[k,]-X[x,]))))
        return(resloc/(2*nloc))
      }
      d <- unlist(lapply(w0,loca))
    }
    attr(d, "Size") <- nlig
    attr(d, "Labels") <- popNames(x)
    attr(d, "Diag") <- diag
    attr(d, "Upper") <- upper
    attr(d, "method") <- METHODS[method]
    attr(d, "call") <- match.call()
    class(d) <- "dist"
    return(d)

} # end method dist for genpop

Try the adegenet package in your browser

Any scripts or data that you put into this service are public.

adegenet documentation built on Feb. 16, 2023, 6 p.m.