File: vbscan.R

package info (click to toggle)
qtl 1.08-56-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 3,552 kB
  • ctags: 242
  • sloc: ansic: 8,903; makefile: 1
file content (183 lines) | stat: -rw-r--r-- 5,242 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
######################################################################
#
# vbscan.R
#
# copyright (c) 2001-7, Karl W Broman
# last modified Jul, 2007
# first written May, 2001
# Licensed under the GNU General Public License version 2 (June, 1991)
# 
# Part of the R/qtl package
# Contains: vbscan
#
######################################################################

######################################################################
#
# vbscan: scan genome for a quantitative phenotype for which some
# individuals' phenotype is undefined (for example, the size of a
# lesion, where some individuals have no lesion).
#
######################################################################

vbscan <-
function(cross, pheno.col=1, upper=FALSE, method="em", maxit=4000,
         tol=1e-4)
{
  method <- match.arg(method)
  type <- class(cross)[1]

  # check arguments are okay
  if(length(pheno.col) > 1) pheno.col <- pheno.col[1]
  if(pheno.col > nphe(cross))
    stop("Specified phenotype column exceeds the number of phenotypes")
  y <- cross$pheno[,pheno.col]

  # modify phenotypes
  if(upper) {
    if(!any(y == Inf)) y[y==max(y)] <- Inf
  }
  else {
    if(!any(y == -Inf)) y[y==min(y)] <- -Inf
  }
  survived <- rep(0,length(y))
  survived[y == -Inf | y == Inf] <- 1

  # The following line is included since .C() doesn't accept Infs
  y[y == -Inf | y == Inf] <- 99999

  n.chr <- nchr(cross)
  results <- NULL

  # to store the degrees of freedom
  dfApm <- dfAp <- dfAm <- -1
  dfXpm <- dfXp <- dfXm <- -1

  for(i in 1:n.chr) {
    # make sure inferred genotypes or genotype probabilities are available
    if(!("prob" %in% names(cross$geno[[i]]))) {
      cat(" -Calculating genotype probabilities\n")
      cross <- calc.genoprob(cross)
    }

    genoprob <- cross$geno[[i]]$prob
    n.pos <- dim(genoprob)[2]
    n.ind <- length(y)

    chrtype <- class(cross$geno[[i]])
    if(chrtype=="X") sexpgm <- getsex(cross)
    else sexpgm <- NULL

    gen.names <- getgenonames(type,chrtype,"full", sexpgm, attributes(cross))
    n.gen <- length(gen.names)

    # revise X chromosome genotypes
    if(chrtype=="X" && (type=="f2" || type=="bc"))
      genoprob <- reviseXdata(type, "full", sexpgm, prob=genoprob,
                              cross.attr=attributes(cross))

    z <- .C("R_vbscan",
            as.integer(n.pos),
            as.integer(n.ind),
            as.integer(n.gen),
            as.double(genoprob),
            as.double(y),
            as.integer(survived),
            lod=as.double(rep(0, n.pos*3)),
            as.integer(maxit),
            as.double(tol),
            PACKAGE="qtl")

    if("map" %in% names(attributes(cross$geno[[i]]$prob)))
      map <- attr(cross$geno[[i]]$prob,"map")
    else {
      stp <- attr(cross$geno[[i]]$prob, "step")
      oe <- attr(cross$geno[[i]]$prob, "off.end")
      
      if("stepwidth" %in% names(attributes(cross$geno[[i]]$prob)))
        stpw <- attr(cross$geno[[i]]$prob, "stepwidth")
      else stpw <- "fixed"
      map <- create.map(cross$geno[[i]]$map,stp,oe,stpw)
    }

    if(is.matrix(map)) map <- map[1,]

    res <- data.frame(chr=rep(names(cross$geno)[i],length(map)),
                      pos = as.numeric(map),
                      matrix(z$lod,nrow=n.pos,byrow=TRUE))

    colnames(res)[-(1:2)] <- c("lod.p.mu","lod.p","lod.mu")

    w <- names(map)
    o <- grep("^loc-*[0-9]+",w)

    if(length(o) > 0) # inter-marker locations cited as "c*.loc*"
      w[o] <- paste("c",names(cross$geno)[i],".",w[o],sep="")
    rownames(res) <- w
    
    z <- res

    if(chrtype=="A" && dfApm < 0) {
      dfApm <- (n.gen-1)*2
      dfAp <- (n.gen-1)
      dfAm <- (n.gen-1)
    }
    # get null log10 likelihood for the X chromosome
    if(chrtype=="X") {

      # determine which covariates belong in null hypothesis
      temp <- scanoneXnull(type, sexpgm)
      adjustX <- temp$adjustX
      parX0 <- temp$parX0
      sexpgmcovar <- temp$sexpgmcovar
      sexpgmcovar.alt <- temp$sexpgmcovar.alt
      
      if(dfXpm < 0) {
        if(adjustX) nc <- ncol(sexpgmcovar)
        else nc <- 1
        dfXp <- dfXm <- n.gen - nc
        dfXpm <- 2*dfXp
      }

      if(adjustX) { # get LOD-score adjustment 
        n.gen <- ncol(sexpgmcovar)+1
        genoprob <- matrix(0,nrow=n.ind,ncol=n.gen)
        for(i in 1:n.gen)
          genoprob[sexpgmcovar.alt==i,i] <- 1

        nullz <- .C("R_vbscan",
            as.integer(1),
            as.integer(n.ind),
            as.integer(n.gen),
            as.double(genoprob),
            as.double(y),
            as.integer(survived),
            lod=as.double(rep(0,(4+2*n.gen))),
            as.integer(maxit),
            as.double(tol),
            PACKAGE="qtl")

        # adjust LOD curve
        for(i in 1:3) z[,i+2] <- z[,i+2] - nullz$lod[i]
      }
    } 

    results <- rbind(results, z)
  }
  
  class(results) <- c("scanone","data.frame")
  attr(results,"method") <- method
  attr(results,"type") <- class(cross)[1]
  attr(results,"model") <- "twopart"

  df <- NULL
  if(dfApm > 0)
    df <- rbind(df, "A"=c("p.mu"=dfApm, "p"=dfAp, "mu"=dfAm))
  if(dfXpm > 0)
    df <- rbind(df, "X"=c("p.mu"=dfXpm, "p"=dfXp, "mu"=dfXm))
  attr(results, "df") <- df

  results
}

# end of vbscan.R