R/ss.R

Defines functions pool snp.cbind snp.rbind

Documented in pool

#setOldClass(c("haplotype", "genotype"), test=TRUE)

#content should be raw - TODO: put restriction 
setClass("SnpMatrix", contains="matrix")

setClass("XSnpMatrix", representation("SnpMatrix", diploid="logical"),
         contains="SnpMatrix")
 
# constructor 
setMethod("initialize", 
          "SnpMatrix",
          function(.Object, ...) {
            if(is.null(.Object)) {
              stop("object is null to constructor");
            }
            .Object <- callNextMethod()
            # Please don't remove the tests - they are to do with promises and not redundant.
            # The accessor methods transparently passes to .Data, the assignment methods are different...
            if(!is.null(dim(.Object)) && (dim(.Object)[1] > 0) && (dim(.Object)[2] > 0)) {
              if (mode(.Object) != "raw") {
                cat("coercing object of mode ", mode(.Object), " to SnpMatrix\n")
                mode(.Object@.Data) <- "raw"
              }
              if (is.null(dimnames(.Object))) {
                cat("object has no names - using numeric order for row/column names\n")
                dimnames(.Object@.Data) <- c(list(as.character(1:(dim(.Object)[1]))), list(as.character(1:(dim(.Object)[2]))))
              }
            }
            .Object
          })

setMethod("initialize", 
          "XSnpMatrix", 
          function(.Object, ...) {
            .Object <- callNextMethod()
            if (length(.Object@diploid)==0){
              warning("diploid slot not supplied; it has been estimated from heterozygosity")
              guess <- .guessPloidy(.Object)
              .Object@diploid <- guess$diploid
              het <- guess$Heterozygosity
            }
            else {
              lend <- length(.Object@diploid)
              if (lend==1)
                .Object@diploid <- rep(.Object@diploid, nrow(.Object))
              else if (lend!=nrow(.Object))
                stop("diploid argument incorrect length")
              dpna <- is.na(.Object@diploid)
              if (any(dpna)) {
                warning("diploid argument contains NAs; these have been replaced by guesses based on heterozygosity")
                guess <- .guessPloidy(.Object, .Object@diploid)
                .Object@diploid <- guess$diploid
                het <- guess$Heterozygosity
              }
              else
                het <- row.summary(.Object)$Heterozygosity               
            }
            hetm <- !.Object@diploid & (!is.na(het)&(het>0))
            if (any(hetm)){
              warning(sum(hetm, na.rm=TRUE),
                      " heterozygous calls for haploid genotypes; these were set to NA")
              .Object@.Data <- .forceHom(.Object@.Data, .Object@diploid)
            }
            .Object
          })

setMethod("[", signature(x="SnpMatrix",i="ANY",j="ANY",drop="ANY"),
          function(x, i, j, drop=FALSE) {
            if (drop!=FALSE)
              stop("dimensions cannot be dropped from a SnpMatrix object")
            
            if (missing(i)) i <- integer(0)
            else if (is.character(i)) {
              i <- match(i, rownames(x))
              if (any(is.na(i)))
                stop("No match for one or more row selections")
            }
            else if (is.numeric(i)) {
              if (any(i<0)) 
                  i <- (1:nrow(x))[i]
              if (min(i)<1 || max(i)>nrow(x)) 
                stop("One or more row selections out of range")
            }
            else if (is.logical(i)) {
              if (length(i)!=nrow(x))
                stop("logical row selection vector is wrong length")
              i <- (1:nrow(x))[i]
            }
            else
              stop("Illegal type for row selection, i")
            i <- as.integer(i)
            if (any(is.na(i)))
              stop("NAs in row selection vector")
            
            if (missing(j)) j <- integer(0)
            else if (is.character(j)) {
              j <- match(j, colnames(x))
              if (any(is.na(j)))
                stop("No match for one or more column selections")
            }
            else if (is.numeric(j)) {
              if (any(j<0))
                j <- (1:ncol(x))[j]
              if (min(j)<1 || max(j)>ncol(x)) 
                stop("One or more column selections out of range")
            }
            else if (is.logical(j)) {
              if (length(j)!=ncol(x))
                stop("logical column selection vector is wrong length")
              j <- (1:ncol(x))[j]
            }
            else
              stop("Illegal type for column selection, j")
            j <- as.integer(j)
            if (any(is.na(j)))
              stop("NAs in column selection vector")
            
            .Call("subset", x, i, j, PACKAGE="snpStats")
          }
)

setMethod("[", signature(x="XSnpMatrix",i="ANY",j="ANY",drop="ANY"),
          function(x, i, j, drop=FALSE) {
            if (drop!=FALSE)
              stop("dimensions cannot be dropped from an XSnpMatrix object")  
            callNextMethod()
           })

# The sub-assignment methods

setMethod("[<-", signature(x="XSnpMatrix",i="ANY",j="ANY",value="XSnpMatrix"),
          function(x, i, j, value) {
            # The raw sub assignment should *just work*:
            if (!missing(i) & !missing(j)) {
              x@.Data[i,j] <- value
            } else if (missing(i) & missing(j)) {
              x@.Data[,] <- value
            } else if (missing(i)) {
              x@.Data[,j] <- value
            } else if (missing(j)) {
              x@.Data[i,] <- value
            }
            # All we want to do is to shuffle the rows
            # if a row index is passed
            if(!missing(i)) {
              slot(x, "diploid")[i] <- slot(value, "diploid")
            }
            x
          })

setAs("SnpMatrix", "numeric",
      function(from) {
        .Call("asnum", from, PACKAGE="snpStats")
      })

setAs("SnpMatrix", "character",
      function(from) {
        df <- dim(from)
        dnames <- dimnames(from)
        from <- 1+as.integer(from)
        to <- ifelse(from<5, c("NA", "A/A", "A/B", "B/B")[from], "Uncertain")
        dim(to) <- df
        dimnames(to) <- dnames
        to
      })

setAs("SnpMatrix", "XSnpMatrix",
      function(from) {
        new("XSnpMatrix", from)
      })

setAs("XSnpMatrix", "character",
      function(from) {
        df <- dim(from)
        ifr <- 1 + as.integer(from)
        offset <-  4*rep(from@diploid, ncol(from))
        to <- ifelse(ifr<5, c("NA", "A", "Error", "B",
                               "NA", "A/A", "A/B", "B/B")[ifr + offset],
                     "Uncertain")
        dim(to) <- df
        dimnames(to) <- dimnames(from)
        to
      })

setAs("matrix", "SnpMatrix",
      function(from) {
        if (is.numeric(from)) {
          valid  <- (from==0 | from==1 | from==2)
          if(!all(is.na(from) | valid)) 
            warning("values other than 0, 1 or 2 set to NA")
          to <- from+1
          to[is.na(from)|!valid] <- 0
          mode(to) <- "raw"
        }
        else if (is.raw(from)) {
          not.valid  <- (from>3)
          if (any(not.valid))
            warning("values other than 01, 02 or 03 set to NA (00)")
          to <- from
          to[not.valid] <- as.raw(0)
        }
        else 
          stop("Can only convert `numeric' or `raw' matrices") 
        new("SnpMatrix", to)
      })
           
# Summary of a SnpMatrix

setGeneric("summary")

setMethod("summary", "SnpMatrix",
   function(object) {
     list(rows = summary(row.summary(object)),
          cols = summary(col.summary(object, uncertain=TRUE)))
   })

setMethod("summary", "XSnpMatrix",
   function(object) {
     tab <- table(object@diploid)
     names(tab) <- ifelse(as.logical(names(tab)), "diploid", "haploid")
     list(sex = tab,
          rows = summary(row.summary(object)),
          cols = summary(col.summary(object, uncertain=TRUE)))
   })

# Imputation

setClass("ImputationRules", contains="list")

setMethod("summary", "ImputationRules",
   function(object) {
     info <- .Call("r2_impute", object, PACKAGE="snpStats")
     i2 <- info[,2]
     levs <- sort(unique(i2))
     labs <- paste(levs, "tags")
     size <- factor(i2, levels= levs, labels=labs)
     r2 <- info[,1]
     r2[r2>1] <- 1
     byr2 <- cut(r2, c((0:9)/10, 0.95, 0.99, 1.0), right=FALSE,
                 include.lowest=TRUE)
     table(byr2, size, dnn=c("R-squared", "SNPs used"), useNA="ifany")
   })

setMethod("[",
       signature(x="ImputationRules", i="ANY", j="missing", drop="missing"),
       function(x, i){
         if (is.character(i))
           i <- match(i, names(x), nomatch=0)
         ss <- x@.Data[i]
         names(ss) <- names(x)[i]
         res <- new("ImputationRules", ss)
         attr(res, "Max.predictors") <-
           max(sapply(res, function(rule) length(rule$snps)))
         res
       })


# Show and plot methods

setMethod("show", "ImputationRules",
   function(object) {
     to <- names(object)
     for (i in 1:length(object)) {
       if (is.null(object[[i]]$snps))
         cat(to[i], "~ No imputation available\n")
       else {
         if (is.null(object[[i]]$hap.probs)) 
           stop("Old imputation rule - not supported by this version")
         else 
           cat(to[i], " ~ ", paste(object[[i]]$snps, collapse="+"))
         cat(" (MAF = ", object[[i]]$maf, 
             ", R-squared = ", object[[i]]$r.squared,
             ")\n", sep="")
       }
     }
   })

setMethod("plot", signature(x="ImputationRules", y="missing"),
   function(x, y, ...) {
     mat <- summary(x)
     n <- nrow(mat)
     m <- ncol(mat)
     if (is.na(rownames(mat)[n])) {
       mat <- mat[-n,-m]
       n <- n-1
       m <- m-1
     }
     val <- barplot(t(mat[n:1,]), legend.text=TRUE, 
                    beside=F, col=heat.colors(m),
                    xlab=expression(r^2), ylab="Number of imputed SNPs",
                    names.arg=rep("", n), cex.lab=1.3, ...)
     mtext(rownames(mat)[n:1], at=val, side=1, las=2, line=0.5, cex=0.8)
    })

setMethod("show", "XSnpMatrix",
   function(object) {
     nr <- nrow(object)
     nc <- ncol(object) 
     dip <- object@diploid
     cat("An XSnpMatrix with ", nr, " rows (", sum(!dip), " haploid and ",
         sum(dip), " diploid), and ", nc, " columns\n", sep="")
     if (nr>1)
       cat("Row names: ", rownames(object)[1],"...", rownames(object)[nr],"\n")
     else
       cat("Row name: ", rownames(object)[1], "\n")
     if (nc>1)
       cat("Col names: ", colnames(object)[1],"...", colnames(object)[nc],"\n")
     else
       cat("Col name: ", colnames(object)[1],"\n")
       
   })

setMethod("show", "SnpMatrix",
   function(object) {
     nr <- nrow(object)
     nc <- ncol(object) 
     cat("A SnpMatrix with ", nr, "rows and ", nc,
         "columns\n")
     if (nr>1)
       cat("Row names: ", rownames(object)[1],"...", rownames(object)[nr],"\n")
     else
       cat("Row name: ", rownames(object)[1],"\n")
     if (nc>1)
       cat("Col names: ", colnames(object)[1],"...", colnames(object)[nc],"\n")
     else
       cat("Col name: ", colnames(object)[1],"\n")
   })


setMethod("is.na", "SnpMatrix", function(x){ x==0})

snp.rbind <- function(...){
  .External("snp_rbind", ..., PACKAGE="snpStats")
}
snp.cbind <- function(...){
  .External("snp_cbind", ..., PACKAGE="snpStats")
}

setMethod("rbind", signature(...="SnpMatrix"), snp.rbind)
setMethod("cbind", signature(...="SnpMatrix"), snp.cbind)



# Tests 

setClass("SingleSnpTests", 
         representation(snp.names="character", chisq="matrix",
                        N="integer", N.r2="numeric"))
setClass("SingleSnpTestsScore", 
         representation("SingleSnpTests", U="matrix", V="matrix"),
         contains="SingleSnpTests")
setClass("GlmTests",
         representation(snp.names="ANY", var.names="character",
                        chisq="numeric", df="integer",
                        N="integer"))
setClass("GlmTestsScore", representation("GlmTests", score="list"),
         contains="GlmTests")

              
setMethod("[",
          signature(x="SingleSnpTests", i="ANY",
                    j="missing", drop="missing"),
          function(x, i, j, drop) {
            if (is.character(i)) {
              i <- match(i, x@snp.names)
              if (any(is.na(i))) {
                warning(sum(is.na(i)),
                        " SNPs couldn't be found in SingleSnpTests object\n")
                i <- i[!is.na(i)]
              }
            } else if (is.logical(i)) {
              if (length(i)!=length(x@snp.names))
                stop("logical selection array has incorrect length")
              i <- (1:length(i))[i]
            } else if (is.numeric(i)) {
              if (min(i)<0 || max(i)>length(x@snp.names))
                stop("selection index out of range")
            } else {
              stop("illegal selection array")
            }
            if (length(x@N.r2)>0)
              N.r2 <- x@N.r2[i]
            else
              N.r2 <- numeric(0)
            new("SingleSnpTests",
              snp.names=x@snp.names[i], chisq=x@chisq[i,, drop=FALSE],
                N=x@N[i], N.r2=N.r2)
          })

setMethod("[",
          signature(x="SingleSnpTestsScore", i="ANY",
                    j="missing", drop="missing"),
          function(x, i, j, drop) {
            if (is.character(i)) {
              i <- match(i, x@snp.names)
              if (any(is.na(i))) {
                warning(sum(is.na(i)),
                        " SNPs couldn't be found in SingleSnpTests object\n")
                i <- i[!is.na(i)]
              }
            } else if (is.logical(i)) {
              if (length(i)!=length(x@snp.names))
                stop("logical selection array has incorrect length")
              i <- (1:length(i))[i]
            } else if (is.numeric(i)) {
              if (min(i)<0 || max(i)>length(x@snp.names))
                stop("selection index out of range")
            } else {
              stop("illegal selection array")
            }
            if (length(x@N.r2)>0)
              N.r2 <- x@N.r2[i]
            else
              N.r2 <- numeric(0)
            new("SingleSnpTestsScore",
              snp.names=x@snp.names[i], chisq=x@chisq[i,,drop=FALSE],
                N=x@N[i], N.r2=N.r2,
                U=x@U[i,,drop=FALSE], V=x@V[i,,drop=FALSE])
          })

setMethod("[",
          signature(x="GlmTests", i="ANY",
                    j="missing", drop="missing"),
           function(x, i, j, drop) {
             if (is.character(i))
               i <- match(i, names(x), nomatch=0)
             new("GlmTests",
                 snp.names = x@snp.names[i],
                 var.names = x@var.names,
                 chisq = x@chisq[i],
                 df = x@df[i],
                 N = x@N[i])
          })

setMethod("[",
          signature(x="GlmTestsScore", i="ANY",
                    j="missing", drop="missing"),
          function(x, i, j, drop) {
            if (is.character(i)) 
              i <- match(i, names(x), nomatch=0)
            new("GlmTestsScore",
                snp.names = x@snp.names[i],
                var.names = x@var.names,
                chisq = x@chisq[i],
                df = x@df[i],
                N = x@N[i],
                score = x@score[i])
          })
                   
setAs("SingleSnpTests", "data.frame",
      function(from) {
        if (length(from@N.r2)>0)
          data.frame(N=from@N, N.r2=from@N.r2,
                     Chi.squared=from@chisq,
                     P.1df=pchisq(from@chisq[,1], df=1, lower.tail=FALSE),
                     P.2df=pchisq(from@chisq[,2], df=2, lower.tail=FALSE),
                     row.names=from@snp.names)
        else
          data.frame(N=from@N,
                     Chi.squared=from@chisq,
                     P.1df=pchisq(from@chisq[,1], df=1, lower.tail=FALSE),
                     P.2df=pchisq(from@chisq[,2], df=2, lower.tail=FALSE),
                     row.names=from@snp.names)
      })

setMethod("summary", "SingleSnpTests",
          function(object) {
            summary(as(object, 'data.frame'))
          })

setMethod("show", "SingleSnpTests",
          function(object) {
            print(as(object, 'data.frame'))
          })

setAs("GlmTests", "data.frame",
      function(from) {
            chi2 <- from@chisq
            df <- from@df
            p <- pchisq(chi2, df=df, lower.tail=FALSE)
            N <- from@N
            data.frame(row.names=names(from),
                               Chi.squared=chi2, Df=df, p.value=p)
          })

setMethod("summary", "GlmTests",
          function(object) {
            summary(as(object, "data.frame"))
          })

setMethod("show", "GlmTests",
          function(object) {
            print(as(object, "data.frame"))
          })

# There are no standard generics for these, but the call to standardGeneric
# avoids a warning message 
  
setGeneric("p.value", function(x, df) standardGeneric("p.value"),
           useAsDefault=FALSE)

setGeneric("chi.squared", function(x, df) standardGeneric("chi.squared"),
           useAsDefault=FALSE)

setGeneric("deg.freedom", function(x) standardGeneric("deg.freedom"),
           useAsDefault=FALSE)

setGeneric("effect.sign", function(x, simplify) standardGeneric("effect.sign"),
           useAsDefault=FALSE)

setGeneric("sample.size", function(x) standardGeneric("sample.size"),
           useAsDefault=FALSE)

setGeneric("effective.sample.size",
           function(x) standardGeneric("effective.sample.size"),
           useAsDefault=FALSE)

setGeneric("pool2", function(x, y, score) standardGeneric("pool2"),
           useAsDefault=FALSE)

setGeneric("names")

setMethod("p.value", signature(x="SingleSnpTests", df="numeric"),
          function(x, df) {
            if (df>2)
              stop("df must be 1 or 2")
            p <- pchisq(x@chisq[,df], df=df, lower.tail=FALSE)
            names(p) <- x@snp.names
            p
          })

setMethod("p.value", signature(x="GlmTests", df="missing"),
          function(x, df) {
            p <- pchisq(q=x@chisq, x@df, lower.tail=FALSE)
            p
          })


setMethod("chi.squared", signature(x="SingleSnpTests", df="numeric"),
          function(x, df) {
            if (df>2)
              stop("df must be 1 or 2")
            chi2 <- x@chisq[,df]
            names(chi2) <- x@snp.names
            chi2
          })

setMethod("chi.squared", signature(x="GlmTests", df="missing"),
          function(x, df) {
            chi2 <- x@chisq
            chi2
          })


setMethod("deg.freedom", signature(x="GlmTests"),
          function(x) {
            df <- x@df
            df
          })

setMethod("effect.sign", signature(x="GlmTests", simplify="logical"),
          function(x, simplify=TRUE) {
            res <- sapply(x@score, function(x) sign(x$U))
            res
         })

setMethod("effect.sign",
          signature(x="SingleSnpTestsScore", simplify="missing"),
          function(x, simplify) {
            res <- sign(x@U[,1])
            names(res) <- x@snp.names
            res
          })

setMethod("sample.size", signature(x="GlmTests"),
          function(x) {
            res <- x@N
            res
          })

setMethod("sample.size", signature(x="SingleSnpTests"),
          function(x) {
            res <- x@N
            names(res) <- x@snp.names
            res
          })

setMethod("effective.sample.size", signature(x="SingleSnpTests"),
          function(x) {
            if (length(x@N.r2)==0)
              res <- x@N
            else
              res <- x@N.r2
            names(res) <- x@snp.names
            res
          })

setMethod("names", signature(x="SingleSnpTests"), function(x) x@snp.names)

setMethod("names", "GlmTests",
          function(x) {
            objn <- x@snp.names
            if (is.list(objn)) {
              nobjn <- attr(objn, "names")
              if (!is.null(nobjn))
                nobjn
              else
                vapply(objn, function(x){
                  paste(x[1],x[length(x)], sep="...")}, "character")
            }
            else
              as.character(objn)
          })

setMethod("pool2",
          signature(x="SingleSnpTestsScore",y="SingleSnpTestsScore",
                    score="logical"),
          function(x, y, score) {
            all.snps <- union(x@snp.names, y@snp.names)
            can.pool <- intersect(x@snp.names, y@snp.names)
            x.only <- setdiff(x@snp.names, can.pool)
            y.only <- setdiff(y@snp.names, can.pool)
            if (length(can.pool)>0) {
              xsel <- match(can.pool, x@snp.names)
              ysel <- match(can.pool, y@snp.names)
              N <- x@N[xsel] + y@N[ysel]
              U <- x@U[xsel,,drop=FALSE] + y@U[ysel,,drop=FALSE]
              V <- x@V[xsel,,drop=FALSE] + y@V[ysel,,drop=FALSE]
              if (length(x@N.r2)>0) {
                if (length(y@N.r2)>0)
                  Nr2 <- x@N.r2[xsel] + y@N.r2[ysel]
                else
                  Nr2 <- x@N.r2[xsel] + y@N[ysel]
              } else {
                if (length(y@N.r2)>0)
                  Nr2 <- x@N[xsel]+  y@N.r2[ysel]
                else
                  Nr2 <- numeric(0)
              }
            } else {
              N <- NULL
              U <- NULL
              V <- NULL
              Nr2 <- numeric(0)
            }
            if (length(x.only)>0) {
              xsel <- match(x.only, x@snp.names)
              U <- rbind(U, x@U[xsel,,drop=FALSE])
              V <- rbind(V, x@V[xsel,,drop=FALSE])
              if (length(Nr2>0)) {
                if (length(x@N.r2)>0) 
                  Nr2 <- c(Nr2, x@N.r2[xsel])
                else
                  Nr2 <- c(Nr2, x@N[xsel])
              } else {
                if (length(x@N.r2)>0)
                  Nr2 <- c(N, x@N.r2[xsel])
              }
              N <- c(N, x@N[xsel])
            }
            if (length(y.only)>0) {
              ysel <- match(y.only, y@snp.names)
              U <- rbind(U, y@U[ysel,,drop=FALSE])
              V <- rbind(V, y@V[ysel,,drop=FALSE])
              if (length(Nr2>0)) {
                if (length(y@N.r2)>0) 
                  Nr2 <- c(Nr2, y@N.r2[ysel])
                else
                  Nr2 <- c(Nr2, y@N[ysel])
              } else {
                if (length(y@N.r2)>0)
                  Nr2 <- c(N, y@N.r2[ysel])
              }
              N <- c(N, y@N[ysel])
            }
            chisq <- .Call("chisq_single", list(U=U, V=V, N=N),
                           PACKAGE="snpStats")
            if (score)
              res <- new("SingleSnpTestsScore",
                         snp.names=c(can.pool, x.only, y.only),
                         chisq=chisq, N=N, U=U, V=V, N.r2=Nr2)
            else
              res <- new("SingleSnpTests",
                         snp.names=c(can.pool, x.only, y.only),
                         chisq=chisq, N=N, N.r2=Nr2)
            res
          })

# need to edit this

setMethod("pool2",
          signature(x="GlmTestsScore",y="GlmTestsScore",
                    score="logical"),
          function(x, y, score) {
            if (!is.null(x@var.names) && !is.null(y@var.names) &&
                (any(x@var.names!=y@var.names)))
              warning("tests to be pooled have non-matching var.names slots") 
            nm.x <- names(x)
            nm.y <- names(y)
            if (any(duplicated(nm.x))||any(duplicated(nm.y)))
              stop("At least one object has duplicated test names")
            to.pool <- intersect(nm.x, nm.y)
            if (length(to.pool)>0) {
              res <- .Call("pool2_glm",
                           x[to.pool],
                           y[to.pool], score, 
                           PACKAGE="snpStats")
 
            }
            else {
              res <- NULL
            }
            x.only <- setdiff(nm.x, to.pool)
            y.only <- setdiff(nm.y, to.pool)
            if (length(x.only)==0 && length(y.only)==0)
              return(res);
            ix <- match(x.only, nm.x, nomatch=0)
            iy <- match(y.only, nm.y, nomatch=0)
            if (is.null(res)) {
              res.chisq <- NULL
              res.df <- NULL
              res.N <- NULL
              res.score <- NULL
            }
            else {
              res.chisq <- res@chisq
              res.df <- res@df
              res.N <- res@N
              if (score)
                res.score <- res@score
            }
            if (score)
              res <- new("GlmTestsScore",
                         snp.names=c(to.pool, x.only, y.only),
                         var.names=x@var.names,
                         chisq=c(res.chisq, x@chisq[ix], y@chisq[iy]),        
                         df=c(res.df, x@df[ix], y@df[iy]),        
                         N=c(res.N, x@N[ix], y@N[iy]),        
                         score=append(res.score,
                           append(x@score[ix], y@score[iy])))
            else
               res <- new("GlmTests",
                          snp.names=c(to.pool, x.only, y.only),
                          var.names=x@var.names,
                          chisq=c(res.chisq, x@chisq[ix], y@chisq[iy]),        
                          df=c(res.df, x@df[ix], y@df[iy]),        
                          N=c(res.N, x@N[ix], y@N[iy]))       
            res
          })

# Switch allele methods 

setGeneric("switch.alleles",
           function(x, snps) standardGeneric("switch.alleles"),
           useAsDefault=FALSE)

setMethod("switch.alleles", signature(x="SnpMatrix", snps="ANY"),
          function(x, snps) {
            if (is.character(snps)) 
              snps <- match(snps, colnames(x))
            else if (is.logical(snps)) {
              if (length(snps)!=ncol(x))
                stop("logical snp selection vector is wrong length")
              snps <- (1:ncol(x))[snps]
            }
            else if (!is.integer(snps))
              stop("snp selection must be character, logical or integer")
            if (any(is.na(snps) | snps>ncol(x) | snps<1))
              stop("illegal snp selection")
            .Call("smat_switch", x, snps, PACKAGE="snpStats")
          })

setMethod("switch.alleles", signature(x="SingleSnpTestsScore", snps="ANY"),
          function(x, snps) {
            if (is.character(snps)) {
              snps <- match(snps, x@snp.names)
              if (any(is.na(snps)))
                warning(sum(is.na(snps)),
                        " SNP names were not found in tests object")
              snps <- snps[!is.na(snps)]
            } 
            ntest <- length(x@snp.names)
            if (is.logical(snps)) {
              if (length(snps)!=ntest)
                stop("incompatible arguments")
              if (sum(snps)==0)
                return(x)
            } else if (is.numeric(snps)) {
              if (length(snps)==0)
                return(x)
              if (max(snps)>ntest || min(snps)<1)
                stop("incompatible arguments")
            } else {
              stop("SNPs to be switched must be indicated by name, position, or by a logical vector")
            }
            res <- x
            res@U[snps,1] <- -x@U[snps,1]
            if (ncol(x@U)==3) {
              res@U[snps,2] <- -x@U[snps,2]
              res@U[snps,3] <- x@U[snps,3] - x@U[snps,2]
              res@V[snps,4] <- x@V[snps,4] - 2*x@V[snps,3] +
                x@V[snps,2]
              res@V[snps,3] <- x@V[snps,3] - x@V[snps,2]
            } else {
              res@U[snps,2] <- x@U[snps,2] - x@U[snps,1]
              res@V[snps,3] <- x@V[snps,3] - 2*x@V[snps,2] +
                x@V[snps,1]
              res@V[snps,2] <- x@V[snps,2] - x@V[snps,1]
            }
            res
          })

## This next will be slow but needed rarely

setMethod("switch.alleles", signature(x="GlmTestsScore",
                                      snps="character"),
          function(x, snps) {
            if (is.list(x@snp.names))
              switch <- lapply(x@snp.names, function(x, y) x%in%y, snps)
            else
              switch <- x@snp.names %in% snps
            N <- length(x@score)
            new.score <- vector("list", N)
            for (i in 1:N) {
              Ui <- x$U
              Vi <- x$V
              Si <- switch[i]
              lu <- length(Ui)
              ls <- length(Si)
              if (lu!=ls) {
                if (lu%%ls)
                  stop("error in GlmTest object")
                Si <- rep(Si, rep(lu/ls, ls))
              }
              new.score[[i]] <- list(U=ifelse(Si, -Ui, Ui), V=Vi)
            }
            new("GlmTestsScore", snp.names=x@snp.names, var.names=x@var.names,
                chisq=x@chisq, df=x@df, N=x@N,
                score=new.score)
          })


pool <- function(..., score=FALSE) {
  argl <- list(...)
  na <- length(argl)
  while (na > 0 && is.null(argl[[na]])) {
    argl <- argl[-na]
    na <- na - 1
  }
  if (na<2)
    stop("need at least two test sets to pool")
  if (na>2) {
    p2 <- pool2(..1, ..2, score=TRUE)
    r <- do.call(pool, c(p2, argl[3:na], score=score))
  }
  else
    r <- pool2(..1, ..2, score=score)
  r
}


## Parameter estimates

setClass("GlmEstimates", contains="list")

setMethod("[", signature("GlmEstimates", i="ANY", j="missing",
                         drop="missing"),
          function(x, i) {
            if (is.character(i))
              i <- match(i, names(x))
            res <- x@.Data[i, drop=FALSE]
            if (length(res)==0)
              return(NULL)
            names(res) <- names(x)[i]
            new("GlmEstimates", res)
           })

setMethod("show", "GlmEstimates",
          function(object) {
            len0 <- max(5, nchar(names(object)))
            len1 <- max(10,
                        sapply(object, function(x)
                               max(if(is.null(x)) 0 else nchar(x$Y.var))))
            len2 <- max(9,
                        sapply(object, function(x)
                               max(if(is.null(x)) 0 else nchar(names(x$beta)))))
            space <- 2
            nwidth <- 10
            di <- 5
            divide <- rep("-", len0+len1+len2+3*nwidth+5*space)
            cat("\n", format("Model", justify="right", width=len0),
                format("Y-variable", justify="right", width=len1+space),
                format("Parameter", justify="right", width=len2+space),
                format("Estimate", justify="right", width=nwidth+space),
                format("S.E.", justify="right", width=nwidth+space),
                format("z-value", justify="right", width=nwidth+space),"\n",
                divide, "\n", sep="")
            labs <- names(object)
            for (j in 1:length(object)) {
              labj <- labs[j]
              x <- object[[j]]
              if (is.null(x)) {
                cat(format(labj, justify="right", width=len1),
                    "- No estimates available\n") 
              }
              else {
                nyj <- x$Y.var
                nb <- length(x$beta)
                namep <- names(x$beta)
                ii <- 0
                for (i in 1:nb){
                  ii <- ii+i
                  bi <- x$beta[i]
                  si <- sqrt(x$Var.beta[ii])
                  zi <- bi/si
                  cat(format(labj, justify="right", width=len0), sep="")
                  cat(format(nyj, justify="right", width=len1+space), sep="")
                  labj <- ""
                  nyj <- ""
                  cat(format(namep[i], justify="right", width=len2+space),
                      format(bi, justify="right", width=nwidth+space,
                             digits=di),
                      format(si, justify="right", width=nwidth+space,
                             digits=di),
                      formatC(zi, format="f", width=nwidth+space, digits=3),
                      "\n", sep="")
                }
              }
              cat(divide, "\n", sep="")
            }
          }
          )

## Wald test

setAs("GlmEstimates", "GlmTests",
      function(from) {
        .Call("wald", from, package="snpStats")
      }
      )
        

## To do

## names method for snp and X.snp

Try the snpStats package in your browser

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

snpStats documentation built on Nov. 8, 2020, 10:59 p.m.