Nothing
######################################################################
#
# plot.R
#
# copyright (c) 2000-2019, Karl W Broman
# [modifications of plot.cross from Brian Yandell]
# last modified Dec, 2019
# first written Mar, 2000
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License,
# version 3, as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but without any warranty; without even the implied warranty of
# merchantability or fitness for a particular purpose. See the GNU
# General Public License, version 3, for more details.
#
# A copy of the GNU General Public License, version 3, is available
# at http://www.r-project.org/Licenses/GPL-3
#
# Part of the R/qtl package
# Contains: plotMissing, plotMap, plot.cross, plotGeno, plotInfo,
# plotPXG, plotPheno
#
######################################################################
plotMissing <-
function(x, chr, reorder=FALSE, main="Missing genotypes",
alternate.chrid=FALSE, ...)
{
cross <- x
if(!inherits(cross, "cross"))
stop("Input should have class \"cross\".")
if(!missing(chr)) cross <- subset(cross,chr=chr)
# get full genotype data into one matrix
Geno <- pull.geno(cross)
# reorder the individuals according to their phenotype
o <- 1:nrow(Geno)
if(reorder) {
# if reorder is a number, use the corresponding phenotype
if(is.numeric(reorder)) {
if(reorder < 1 || reorder > nphe(cross))
stop("reorder should be TRUE, FALSE, or an integer between 1 and", nphe(cross))
o <- order(cross$pheno[,reorder])
}
# otherwise, order according to the sum of the numeric phenotypes
else {
wh <- sapply(cross$pheno, is.numeric)
o <- order(apply(cross$pheno[,wh,drop=FALSE],1,sum))
}
}
# make matrix with 0 where genotype data is missing
# 1 where data is not missing
# 0.5 where data is partially missing
type <- crosstype(cross)
g <- t(Geno[o,])
g[is.na(g)] <- 0
if(type == "bc" || type=="risib" || type=="riself" || type=="bc")
g[g > 0] <- 1
else if(type=="f2") {
g[g > 0 & g < 4] <- 1
g[g > 3] <- 0.5
}
else if(type=="4way") {
g[g > 0 & g < 5] <- 1
g[g > 4] <- 0.5
}
else {
g[g > 0] <- 1
}
old.xpd <- par("xpd")
old.las <- par("las")
par(xpd=TRUE,las=1)
on.exit(par(xpd=old.xpd,las=old.las))
colors <- c("#000000", "gray80", "#FFFFFF")
# plot grid with black pixels where there is missing data
image(1:nrow(g),1:ncol(g),g,ylab="Individuals",xlab="Markers",col=colors,zlim=c(0,1))
# plot lines at the chromosome boundaries
n.mar <- nmar(cross)
n.chr <- nchr(cross)
a <- c(0.5,cumsum(n.mar)+0.5)
# the following makes the lines go slightly above the plotting region
b <- par("usr")
segments(a,b[3],a,b[4]+diff(b[3:4])*0.02)
# this line adds a line above the image
# (the image function seems to leave it out)
abline(h=0.5+c(0,ncol(g)),xpd=FALSE)
# add chromosome numbers
a <- par("usr")
wh <- cumsum(c(0.5,n.mar))
x <- 1:n.chr
for(i in 1:n.chr)
x[i] <- mean(wh[i+c(0,1)])
thechr <- names(cross$geno)
if(!alternate.chrid || length(thechr) < 2) {
for(i in seq(along=x))
axis(side=3, at=x[i], thechr[i], tick=FALSE, line=-0.5)
}
else {
odd <- seq(1, length(x), by=2)
even <- seq(2, length(x), by=2)
for(i in odd) {
axis(side=3, at=x[i], labels=thechr[i], line=-0.75, tick=FALSE)
}
for(i in even) {
axis(side=3, at=x[i], labels=thechr[i], line=+0, tick=FALSE)
}
}
title(main=main)
invisible()
}
geno.image <-
function(x, chr, reorder=FALSE, main="Genotype data",
alternate.chrid=FALSE, col=NULL, ...)
{
cross <- x
if(!inherits(cross, "cross"))
stop("Input should have class \"cross\".")
if(!missing(chr)) cross <- subset(cross,chr=chr)
type <- crosstype(cross)
# revise X chromosome data
if(type=="bc" || type=="f2") {
chr_type <- sapply(cross$geno, chrtype)
if(any(chr_type=="X")) {
for(i in which(chr_type=="X"))
cross$geno[[i]]$data <- reviseXdata(type, "simple", getsex(cross),
geno=cross$geno[[i]]$data,
cross.attr=attributes(cross))
}
}
# get full genotype data into one matrix
Geno <- pull.geno(cross)
# colors to use
maxgeno <- max(Geno, na.rm=TRUE)
if(type != "4way") {
thecolors <- c("white", "#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00")
thebreaks <- seq(-0.5, 5.5, by=1)
}
else {
if(maxgeno <= 5) {
thecolors <- c("white", "#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00")
thebreaks <- seq(-0.5, 5.5, by=1)
}
else {
thecolors <- c("white", "#8DD3C7", "#FFFFB3", "#BEBADA", "#FB8072",
"#80B1D3", "#FDB462", "#B3DE69", "#FCCDE5", "#D9D9D9", "#BC80BD")
thebreaks <- seq(-0.5, 10.5, by=1)
}
}
thecolors <- thecolors[1:(maxgeno+1)]
thebreaks <- thebreaks[1:(maxgeno+2)]
if(!is.null(col)) { # colors provided
if(length(col) < length(thecolors)) {
warning("col should have length ", maxgeno+1)
thecolors[seq_along(col)] <- col
}
else {
thecolors <- col[1:(maxgeno+1)]
}
}
# reorder the individuals according to their phenotype
o <- 1:nrow(Geno)
if(reorder) {
# if reorder is a number, use the corresponding phenotype
if(is.numeric(reorder)) {
if(reorder < 1 || reorder > nphe(cross))
stop("reorder should be TRUE, FALSE, or an integer between 1 and ", nphe(cross))
o <- order(cross$pheno[,reorder])
}
# otherwise, order according to the sum of the numeric phenotypes
else {
wh <- sapply(cross$pheno, is.numeric)
o <- order(apply(cross$pheno[,wh,drop=FALSE],1,sum))
}
}
g <- t(Geno[o,])
g[is.na(g)] <- 0
# make matrix with 0 where genotype data is missing
# 1 where data is not missing
# 0.5 where data is partially missing
old.xpd <- par("xpd")
old.las <- par("las")
par(xpd=TRUE,las=1)
on.exit(par(xpd=old.xpd,las=old.las))
# plot grid with black pixels where there is missing data
plot_image_sub <-
function(g, ylab="Individuals",xlab="Markers", col=thecolors, ...)
{
if(length(thebreaks) != length(col)+1)
stop("Must have one more break than color\n",
"length(breaks) = ", length(thebreaks),
"\nlength(col) = ", length(col))
image(1:nrow(g),1:ncol(g), g, col=col, xlab=xlab, ylab=ylab,
breaks=thebreaks, ...)
}
plot_image_sub(g, ...)
# plot lines at the chromosome boundaries
n.mar <- nmar(cross)
n.chr <- nchr(cross)
a <- c(0.5,cumsum(n.mar)+0.5)
# the following makes the lines go slightly above the plotting region
b <- par("usr")
segments(a,b[3],a,b[4]+diff(b[3:4])*0.02)
# this line adds a line above the image
# (the image function seems to leave it out)
abline(h=0.5+c(0,ncol(g)),xpd=FALSE)
# add chromosome numbers
a <- par("usr")
wh <- cumsum(c(0.5,n.mar))
x <- 1:n.chr
for(i in 1:n.chr)
x[i] <- mean(wh[i+c(0,1)])
thechr <- names(cross$geno)
if(!alternate.chrid || length(thechr) < 2) {
for(i in seq(along=x))
axis(side=3, at=x[i], thechr[i], tick=FALSE, line=-0.5)
}
else {
odd <- seq(1, length(x), by=2)
even <- seq(2, length(x), by=2)
for(i in odd)
axis(side=3, at=x[i], labels=thechr[i], line=-0.75, tick=FALSE)
for(i in even)
axis(side=3, at=x[i], labels=thechr[i], line=+0, tick=FALSE)
}
title(main=main)
invisible()
}
plotMap <- plot.map <-
function(x, map2, chr, horizontal=FALSE, shift=TRUE,
show.marker.names=FALSE, alternate.chrid=FALSE, ...)
{
dots <- list(...)
if("main" %in% names(dots)) {
themain <- dots$main
usemaindefault <- FALSE
}
else usemaindefault <- TRUE
if("xlim" %in% names(dots)) {
xlim <- dots$xlim
usexlimdefault <- FALSE
}
else usexlimdefault <- TRUE
if("ylim" %in% names(dots)) {
ylim <- dots$ylim
useylimdefault <- FALSE
}
else useylimdefault <- TRUE
if("xlab" %in% names(dots))
xlab <- dots$xlab
else {
if(horizontal)
xlab <- "Location (cM)"
else
xlab <- "Chromosome"
}
if("ylab" %in% names(dots))
ylab <- dots$ylab
else {
if(horizontal)
ylab <- "Chromosome"
else
ylab <- "Location (cM)"
}
map <- x
# figure out if the input is a cross (containing a map)
# or is the map itself
if(inherits(map, "cross"))
map <- pull.map(map)
if(!missing(map2) && inherits(map2, "cross"))
map2 <- pull.map(map2)
if(!inherits(map, "map") || (!missing(map2) && !inherits(map2, "map")))
warning("Input should have class \"cross\" or \"map\".")
if(!missing(map2) && is.matrix(map[[1]]) != is.matrix(map2[[1]]))
stop("Maps must be both sex-specific or neither sex-specific.")
if(!missing(chr)) {
map <- map[matchchr(chr, names(map))]
if(!missing(map2)) map2 <- map2[matchchr(chr, names(map2))]
}
sex.sp <- FALSE
if(is.matrix(map[[1]])) { # sex-specific map
one.map <- FALSE
sex.sp <- TRUE
if(!missing(map2)) {
if(is.logical(map2)) {
horizontal <- map2
map2 <- lapply(map,function(a) a[2,])
map <- lapply(map,function(a) a[1,])
}
else {
Map1 <- lapply(map,function(a) a[1,,drop=TRUE])
Map2 <- lapply(map,function(a) a[2,,drop=TRUE])
Map3 <- lapply(map2,function(a) a[1,,drop=TRUE])
Map4 <- lapply(map2,function(a) a[2,,drop=TRUE])
old.mfrow <- par("mfrow")
on.exit(par(mfrow=old.mfrow))
par(mfrow=c(2,1))
class(Map1) <- class(Map2) <- class(Map3) <- class(Map4) <- "map"
plotMap(Map1,Map3,horizontal=horizontal,shift=shift,
show.marker.names=show.marker.names,alternate.chrid=alternate.chrid)
plotMap(Map2,Map4,horizontal=horizontal,shift=shift,
show.marker.names=show.marker.names,alternate.chrid=alternate.chrid)
return(invisible(NULL))
}
}
else {
map2 <- lapply(map,function(a) a[2,])
map <- lapply(map,function(a) a[1,])
}
}
else { # single map
# determine whether a second map was given
if(!missing(map2))
one.map <- FALSE
else one.map <- TRUE
}
if(one.map) {
n.chr <- length(map)
if(!show.marker.names) { # locations of chromosomes
chrpos <- 1:n.chr
thelim <- range(chrpos)+c(-0.5, 0.5)
}
else {
chrpos <- seq(1, n.chr*2, by=2)
thelim <- range(chrpos)+c(-0.35, 2.35)
}
if(shift) map <- lapply(map, function(a) a-a[1])
maxlen <- max(unlist(lapply(map,max)))
if(horizontal) {
old.xpd <- par("xpd")
old.las <- par("las")
par(xpd=TRUE, las=1)
on.exit(par(xpd=old.xpd,las=old.las))
if(usexlimdefault) xlim <- c(0,maxlen)
if(useylimdefault) ylim <- rev(thelim)
plot(0,0,type="n",xlim=xlim, ylim=ylim,yaxs="i",
xlab=xlab, ylab=ylab, yaxt="n")
a <- par("usr")
for(i in 1:n.chr) {
segments(min(map[[i]]), chrpos[i], max(map[[i]]), chrpos[i])
segments(map[[i]], chrpos[i]-0.25, map[[i]], chrpos[i]+0.25)
if(show.marker.names)
text(map[[i]], chrpos[i]+0.35, names(map[[i]]), srt=90, adj=c(1,0.5))
}
# add chromosome labels
if(!alternate.chrid || length(chrpos) < 2) {
for(i in seq(along=chrpos))
axis(side=2, at=chrpos[i], labels=names(map)[i])
}
else {
odd <- seq(1, length(chrpos), by=2)
even <- seq(2, length(chrpos), by=2)
for(i in odd) {
axis(side=2, at=chrpos[i], labels="")
axis(side=2, at=chrpos[i], labels=names(map)[i], line=-0.4, tick=FALSE)
}
for(i in even) {
axis(side=2, at=chrpos[i], labels="")
axis(side=2, at=chrpos[i], labels=names(map)[i], line=+0.4, tick=FALSE)
}
}
}
else {
old.xpd <- par("xpd")
old.las <- par("las")
par(xpd=TRUE,las=1)
on.exit(par(xpd=old.xpd,las=old.las))
if(usexlimdefault) xlim <- thelim
if(useylimdefault) ylim <- c(maxlen, 0)
plot(0,0,type="n",ylim=ylim,xlim=xlim,xaxs="i",
xlab=xlab, ylab=ylab, xaxt="n")
a <- par("usr")
for(i in 1:n.chr) {
segments(chrpos[i], min(map[[i]]), chrpos[i], max(map[[i]]))
segments(chrpos[i]-0.25, map[[i]], chrpos[i]+0.25, map[[i]])
if(show.marker.names)
text(chrpos[i]+0.35, map[[i]], names(map[[i]]), adj=c(0,0.5))
}
# add chromosome labels
if(!alternate.chrid || length(chrpos) < 2) {
for(i in seq(along=chrpos))
axis(side=1, at=chrpos[i], labels=names(map)[i])
}
else {
odd <- seq(1, length(chrpos), by=2)
even <- seq(2, length(chrpos), by=2)
for(i in odd) {
axis(side=1, at=chrpos[i], labels="")
axis(side=1, at=chrpos[i], labels=names(map)[i], line=-0.4, tick=FALSE)
}
for(i in even) {
axis(side=1, at=chrpos[i], labels="")
axis(side=1, at=chrpos[i], labels=names(map)[i], line=+0.4, tick=FALSE)
}
}
}
if(usemaindefault)
title(main="Genetic map")
else if(themain != "")
title(main=themain)
}
else {
map1 <- map
# check that maps conform
if(is.matrix(map2[[1]]))
stop("Second map appears to be a sex-specific map.")
if(length(map1) != length(map2))
stop("Maps have different numbers of chromosomes.")
if(any(names(map1) != names(map2))) {
cat("Map1: ", names(map1), "\n")
cat("Map2: ", names(map2), "\n")
stop("Maps have different chromosome names.")
}
if(shift) {
map1 <- lapply(map1,function(a) a-a[1])
map2 <- lapply(map2,function(a) a-a[1])
}
n.mar1 <- sapply(map1, length)
n.mar2 <- sapply(map2, length)
markernames1 <- lapply(map1, names)
markernames2 <- lapply(map2, names)
if(any(n.mar1 != n.mar2)) {
if(show.marker.names) {
warning("Can't show marker names because of different numbers of markers.")
show.marker.names <- FALSE
}
}
else if(any(unlist(markernames1) != unlist(markernames2))) {
if(show.marker.names) {
warning("Can't show marker names because markers in different orders.")
show.marker.names <- FALSE
}
}
n.chr <- length(map1)
maxloc <- max(c(unlist(lapply(map1,max)),unlist(lapply(map2,max))))
if(!show.marker.names) { # locations of chromosomes
chrpos <- 1:n.chr
thelim <- range(chrpos)+c(-0.5, 0.5)
}
else {
chrpos <- seq(1, n.chr*2, by=2)
thelim <- range(chrpos)+c(-0.4, 2.4)
}
if(!horizontal) {
old.xpd <- par("xpd")
old.las <- par("las")
par(xpd=TRUE,las=1)
on.exit(par(xpd=old.xpd,las=old.las))
if(usexlimdefault) xlim <- thelim
if(useylimdefault) ylim <- c(maxloc, 0)
plot(0,0,type="n",ylim=ylim,xlim=xlim, xaxs="i",
xlab=xlab, ylab=ylab, xaxt="n")
a <- par("usr")
for(i in 1:n.chr) {
if(max(map2[[i]]) < max(map1[[i]]))
map2[[i]] <- map2[[i]] + (max(map1[[i]])-max(map2[[i]]))/2
else
map1[[i]] <- map1[[i]] + (max(map2[[i]])-max(map1[[i]]))/2
segments(chrpos[i]-0.3, min(map1[[i]]), chrpos[i]-0.3, max(map1[[i]]))
segments(chrpos[i]+0.3, min(map2[[i]]), chrpos[i]+0.3, max(map2[[i]]))
# lines between markers
wh <- match(markernames1[[i]], markernames2[[i]])
for(j in which(!is.na(wh)))
segments(chrpos[i]-0.3, map1[[i]][j], chrpos[i]+0.3, map2[[i]][wh[j]])
if(any(is.na(wh)))
segments(chrpos[i]-0.4, map1[[i]][is.na(wh)], chrpos[i]-0.2, map1[[i]][is.na(wh)])
wh <- match(markernames2[[i]], markernames1[[i]])
if(any(is.na(wh)))
segments(chrpos[i]+0.4, map2[[i]][is.na(wh)], chrpos[i]+0.2, map2[[i]][is.na(wh)])
if(show.marker.names)
text(chrpos[i]+0.35, map2[[i]], names(map2[[i]]), adj=c(0,0.5))
}
# add chromosome labels
if(!alternate.chrid || length(chrpos) < 2) {
for(i in seq(along=chrpos))
axis(side=1, at=chrpos[i], labels=names(map1)[i])
}
else {
odd <- seq(1, length(chrpos), by=2)
even <- seq(2, length(chrpos), by=2)
for(i in odd) {
axis(side=1, at=chrpos[i], labels="")
axis(side=1, at=chrpos[i], labels=names(map1)[i], line=-0.4, tick=FALSE)
}
for(i in even) {
axis(side=1, at=chrpos[i], labels="")
axis(side=1, at=chrpos[i], labels=names(map1)[i], line=+0.4, tick=FALSE)
}
}
}
else {
old.xpd <- par("xpd")
old.las <- par("las")
par(xpd=TRUE,las=1)
on.exit(par(xpd=old.xpd,las=old.las))
if(usexlimdefault) xlim <- c(0,maxloc)
if(useylimdefault) ylim <- rev(thelim)
plot(0,0,type="n",xlim=xlim,ylim=ylim,
xlab=xlab, ylab=ylab, yaxt="n", yaxs="i")
a <- par("usr")
for(i in 1:n.chr) {
if(max(map2[[i]]) < max(map1[[i]]))
map2[[i]] <- map2[[i]] + (max(map1[[i]])-max(map2[[i]]))/2
else
map1[[i]] <- map1[[i]] + (max(map2[[i]])-max(map1[[i]]))/2
segments(min(map1[[i]]), chrpos[i]-0.3, max(map1[[i]]), chrpos[[i]]-0.3)
segments(min(map2[[i]]), chrpos[i]+0.3, max(map2[[i]]), chrpos[[i]]+0.3)
# lines between markers
wh <- match(markernames1[[i]], markernames2[[i]])
for(j in which(!is.na(wh)))
segments(map1[[i]][j], chrpos[i]-0.3, map2[[i]][wh[j]], chrpos[i]+0.3)
if(any(is.na(wh)))
segments(map1[[i]][is.na(wh)], chrpos[i]-0.4, map1[[i]][is.na(wh)], chrpos[i]-0.2)
wh <- match(markernames2[[i]], markernames1[[i]])
if(any(is.na(wh)))
segments(map2[[i]][is.na(wh)], chrpos[i]+0.4, map2[[i]][is.na(wh)], chrpos[i]+0.2)
if(show.marker.names)
text(map2[[i]], chrpos[i]+0.35, names(map2[[i]]), srt=90, adj=c(1,0.5))
}
# add chromosome labels
if(!alternate.chrid || length(chrpos) < 2) {
for(i in seq(along=chrpos))
axis(side=2, at=chrpos[i], labels=names(map1)[i])
}
else {
odd <- seq(1, length(chrpos), by=2)
even <- seq(2, length(chrpos), by=2)
for(i in odd) {
axis(side=2, at=chrpos[i], labels="")
axis(side=2, at=chrpos[i], labels=names(map1)[i], line=-0.4, tick=FALSE)
}
for(i in even) {
axis(side=2, at=chrpos[i], labels="")
axis(side=2, at=chrpos[i], labels=names(map1)[i], line=+0.4, tick=FALSE)
}
}
}
if(usemaindefault) {
if(!sex.sp) title(main="Comparison of genetic maps")
else title(main="Genetic map")
}
else if(themain != "")
title(main=themain)
}
invisible()
}
plot.cross <-
function (x, auto.layout = TRUE, pheno.col,
alternate.chrid=TRUE, ...)
{
# look to see whether this should really be shipped to plotMap
if(inherits(auto.layout, "map") &&
(inherits(x, "map") || inherits(x, "cross"))) {
plotMap(x, auto.layout, alternate.chrid=alternate.chrid, ...)
return(invisible())
}
# make sure this is a cross
if(!inherits(x, "cross"))
stop("Input should have class \"cross\".")
old.yaxt <- par("yaxt")
old.mfrow <- par("mfrow")
on.exit(par(yaxt = old.yaxt, mfrow = old.mfrow))
n.phe <- nphe(x)
if(missing(pheno.col)) pheno.col <- 1:n.phe
if(is.character(pheno.col)) {
temp <- match(pheno.col, names(x$pheno))
if(any(is.na(temp)))
warning("Some phenotypes not found:",
paste(pheno.col[is.na(temp)], collapse=" "))
pheno.col <- temp[!is.na(temp)]
}
else pheno.col <- (1:nphe(x))[pheno.col]
n.plot = length(pheno.col) + 2
# automatically choose row/column structure for the plots
if(auto.layout) {
nr <- ceiling(sqrt(n.plot))
nc <- ceiling((n.plot)/nr)
par(mfrow = c(nr, nc))
}
plotMissing(x,alternate.chrid=alternate.chrid)
plotMap(x,alternate.chrid=alternate.chrid)
for(i in pheno.col) plotPheno(x, pheno.col=i)
invisible()
}
##################################################r####################
#
# plotGeno: Plot genotypes for a specified chromosome, with likely
# genotyping errors indicated.
#
######################################################################
plotGeno <-
function(x, chr, ind, include.xo=TRUE, horizontal=TRUE,
cutoff=4, min.sep=2, cex=1.2, ...)
{
cross <- x
if(!inherits(cross, "cross"))
stop("Input should have class \"cross\".")
if(missing(chr)) chr <- names(cross$geno)[1]
cross <- subset(cross,chr=chr)
if(nchr(cross) > 1)
cross <- subset(cross,chr=names(cross$geno)[1])
if(!missing(ind)) {
if(is.null(getid(cross))) cross$pheno$id <- 1:nind(cross)
if(!is.logical(ind)) ind <- unique(ind)
cross <- subset(cross, ind=ind)
}
id <- getid(cross)
if(is.null(id)) id <- 1:nind(cross)
use.id <- TRUE
type <- crosstype(cross)
old.las <- par("las")
on.exit(par(las=old.las))
par(las=1)
if(!("errorlod" %in% names(cross$geno[[1]]))) {
warning("First running calc.errorlod.")
cross <- calc.errorlod(cross,error.prob=0.01)
}
# indicators for apparent errors
errors <- matrix(0,ncol=ncol(cross$geno[[1]]$data),
nrow=nrow(cross$geno[[1]]$data))
dimnames(errors) <- dimnames(cross$geno[[1]]$data)
top <- top.errorlod(cross,names(cross$geno)[1],cutoff,FALSE)
if(length(top) > 0)
for(i in 1:nrow(top))
errors[match(top[i,2],id),as.character(top[i,3])] <- 1
# map, data, errors
map <- cross$geno[[1]]$map
if(is.matrix(map)) map <- map[1,] # if sex-specific map
L <- diff(range(map))
min.d <- L*min.sep/100
d <- diff(map)
d[d < min.d] <- min.d
map <- cumsum(c(0,d))
cross$geno[[1]]$map <- map
n.ind <- nrow(errors)
color <- c("white","gray60","black","green","orange","red")
# revise X chr data for backcross/intercross
data <- cross$geno[[1]]$data
chr_type <- chrtype(cross$geno[[1]])
if(chr_type=="X" && (type=="f2" || type=="bc"))
data <- reviseXdata(type, sexpgm=getsex(cross), geno=data, cross.attr=attributes(cross), force=TRUE)
if(include.xo) {
if(type != "4way") { # find crossover locations
xoloc <- locateXO(cross)
xoloc <- data.frame(ind=rep(1:length(xoloc),sapply(xoloc,length)),
loc=unlist(xoloc), stringsAsFactors=TRUE)
}
else { # 4-way cross
mcross <- dcross <- cross
class(mcross) <- class(dcross) <- c("bc", "cross")
mcross$geno[[1]]$data[!is.na(data) & data==1 | data==3 | data==5] <- 1
mcross$geno[[1]]$data[!is.na(data) & data==2 | data==4 | data==6] <- 2
mcross$geno[[1]]$data[!is.na(data) & data==7 | data==8 | data==9 | data==10] <- NA
dcross$geno[[1]]$data[!is.na(data) & data==1 | data==2 | data==7] <- 1
dcross$geno[[1]]$data[!is.na(data) & data==3 | data==4 | data==8] <- 2
dcross$geno[[1]]$data[!is.na(data) & data==5 | data==6 | data==9 | data==10] <- NA
mxoloc <- locateXO(mcross)
mxoloc <- data.frame(ind=rep(1:length(mxoloc),sapply(mxoloc,length)),
loc=unlist(mxoloc), stringsAsFactors=TRUE)
dxoloc <- locateXO(dcross)
dxoloc <- data.frame(ind=rep(1:length(dxoloc),sapply(dxoloc,length)),
loc=unlist(dxoloc), stringsAsFactors=TRUE)
}
}
# check for 'main' in the ...
args <- list(...)
if("main" %in% names(args))
themain <- args$main
else
themain <- paste("Chromosome",names(cross$geno)[1])
# check for 'xlim' and 'ylim'
if("xlim" %in% names(args)) thexlim <- args$xlim
else thexlim <- NULL
if("ylim" %in% names(args)) theylim <- args$ylim
else theylim <- NULL
if(type=="4way") {
jit <- 0.15
mdata <- data
ddata <- data
# mom's allele
mdata[!is.na(data) & (data==1 | data==3 | data==5)] <- 1
mdata[!is.na(data) & (data==2 | data==4 | data==6)] <- 2
mdata[!is.na(data) & (data==7 | data==8)] <- NA
# dad's allele
ddata[!is.na(data) & (data==1 | data==2 | data==7)] <- 1
ddata[!is.na(data) & (data==3 | data==4 | data==8)] <- 2
ddata[!is.na(data) & (data==5 | data==6)] <- NA
if(horizontal) {
if(is.null(thexlim)) thexlim <- c(0, max(map))
if(is.null(theylim)) theylim <- c(n.ind+1, 0)
plot(0,0,type="n",xlab="Location (cM)",ylab="Individual",
main=themain,
ylim=theylim,xlim=thexlim, yaxt="n", yaxs="i")
segments(0, 1:n.ind-jit, max(map), 1:n.ind-jit)
segments(0, 1:n.ind+jit, max(map), 1:n.ind+jit)
if(use.id) axis(side=2, at=1:n.ind, labels=id)
else axis(side=2, at=1:n.ind)
# A alleles
tind <- rep(1:n.ind,length(map));tind[is.na(mdata)] <- NA
ind <- tind; ind[!is.na(mdata) & mdata!=1] <- NA
x <- rep(map,rep(n.ind,length(map)))
points(x,ind-jit,pch=21,col="black", bg=color[1],cex=cex)
# B alleles
tind <- rep(1:n.ind,length(map));tind[is.na(mdata)] <- NA
ind <- tind; ind[!is.na(mdata) & mdata!=2] <- NA
x <- rep(map,rep(n.ind,length(map)))
points(x,ind-jit,pch=21,col="black", bg=color[3],cex=cex)
# 9/10 genotypes
tind <- rep(1:n.ind,length(map));tind[is.na(mdata)] <- NA
ind <- tind; ind[!is.na(mdata) & mdata!=9] <- NA
x <- rep(map,rep(n.ind,length(map)))
points(x,ind-jit,pch=21,col="black", bg=color[4],cex=cex)
tind <- rep(1:n.ind,length(map));tind[is.na(mdata)] <- NA
ind <- tind; ind[!is.na(mdata) & mdata!=10] <- NA
x <- rep(map,rep(n.ind,length(map)))
points(x,ind-jit,pch=21,col="black", bg=color[5],cex=cex)
# C alleles
tind <- rep(1:n.ind,length(map));tind[is.na(ddata)] <- NA
ind <- tind; ind[!is.na(ddata) & ddata!=1] <- NA
x <- rep(map,rep(n.ind,length(map)))
points(x,ind+jit,pch=21,col="black", bg=color[1],cex=cex)
# D alleles
tind <- rep(1:n.ind,length(map));tind[is.na(ddata)] <- NA
ind <- tind; ind[!is.na(ddata) & ddata!=2] <- NA
x <- rep(map,rep(n.ind,length(map)))
points(x,ind+jit,pch=21,col="black", bg=color[3],cex=cex)
# 9/10 genotypes
tind <- rep(1:n.ind,length(map));tind[is.na(ddata)] <- NA
ind <- tind; ind[!is.na(ddata) & ddata!=9] <- NA
x <- rep(map,rep(n.ind,length(map)))
points(x,ind+jit,pch=21,col="black", bg=color[4],cex=cex)
tind <- rep(1:n.ind,length(map));tind[is.na(ddata)] <- NA
ind <- tind; ind[!is.na(ddata) & ddata!=10] <- NA
x <- rep(map,rep(n.ind,length(map)))
points(x,ind+jit,pch=21,col="black", bg=color[5],cex=cex)
# plot map
u <- par("usr")
segments(map,u[3],map,u[3]-1/2)
segments(map,u[4],map,u[4]+1/2)
if(any(errors != 0)) {
ind <- rep(1:n.ind,length(map));ind[errors!=1]<-NA
points(x,ind-jit,pch=0,col=color[6],cex=cex+0.4,lwd=2)
points(x,ind+jit,pch=0,col=color[6],cex=cex+0.4,lwd=2)
}
if(include.xo) {
points(mxoloc$loc,mxoloc$ind-jit,pch=4,col="blue",lwd=2)
points(dxoloc$loc,dxoloc$ind+jit,pch=4,col="blue",lwd=2)
}
}
else {
if(is.null(theylim)) theylim <- c(max(map), 0)
if(is.null(thexlim)) thexlim <- c(0, n.ind+1)
plot(0,0,type="n",ylab="Location (cM)",xlab="Individual",
main=themain,
xlim=thexlim,ylim=theylim, xaxt="n", xaxs="i")
segments(1:n.ind-jit, 0, 1:n.ind-jit, max(map))
segments(1:n.ind+jit, 0, 1:n.ind+jit, max(map))
if(use.id) axis(side=1, at=1:n.ind, labels=id)
else axis(side=1, at=1:n.ind)
# A alleles
tind <- rep(1:n.ind,length(map));tind[is.na(mdata)] <- NA
ind <- tind; ind[!is.na(mdata) & mdata!=1] <- NA
y <- rep(map,rep(n.ind,length(map)))
points(ind-jit,y,pch=21,col="black",bg=color[1],cex=cex)
# B alleles
tind <- rep(1:n.ind,length(map));tind[is.na(mdata)] <- NA
ind <- tind; ind[!is.na(mdata) & mdata!=2] <- NA
y <- rep(map,rep(n.ind,length(map)))
points(ind-jit,y,pch=21,col="black",bg=color[3],cex=cex)
# 9/10 genotypes
tind <- rep(1:n.ind,length(map));tind[is.na(mdata)] <- NA
ind <- tind; ind[!is.na(mdata) & mdata!=9] <- NA
y <- rep(map,rep(n.ind,length(map)))
points(ind-jit,y,pch=21,col="black", bg=color[4],cex=cex)
tind <- rep(1:n.ind,length(map));tind[is.na(mdata)] <- NA
ind <- tind; ind[!is.na(mdata) & mdata!=10] <- NA
y <- rep(map,rep(n.ind,length(map)))
points(ind-jit,y,pch=21,col="black", bg=color[5],cex=cex)
# C alleles
tind <- rep(1:n.ind,length(map));tind[is.na(ddata)] <- NA
ind <- tind; ind[!is.na(ddata) & ddata!=1] <- NA
y <- rep(map,rep(n.ind,length(map)))
points(ind+jit,y,pch=21,col="black", bg=color[1],cex=cex)
# D alleles
tind <- rep(1:n.ind,length(map));tind[is.na(ddata)] <- NA
ind <- tind; ind[!is.na(ddata) & ddata!=2] <- NA
y <- rep(map,rep(n.ind,length(map)))
points(ind+jit,y,pch=21,col="black", bg=color[3],cex=cex)
# 9/10 genotypes
tind <- rep(1:n.ind,length(map));tind[is.na(ddata)] <- NA
ind <- tind; ind[!is.na(ddata) & ddata!=9] <- NA
y <- rep(map,rep(n.ind,length(map)))
points(ind+jit,y,pch=21,col="black", bg=color[4],cex=cex)
tind <- rep(1:n.ind,length(map));tind[is.na(ddata)] <- NA
ind <- tind; ind[!is.na(ddata) & ddata!=10] <- NA
y <- rep(map,rep(n.ind,length(map)))
points(ind+jit,y,pch=21,col="black", bg=color[5],cex=cex)
# plot map
u <- par("usr")
segments(u[1],map,(u[1]+1)/2,map)
segments(u[2],map,(n.ind+u[2])/2,map)
if(any(errors != 0)) {
ind <- rep(1:n.ind,length(map));ind[errors!=1]<-NA
points(ind-jit,y,pch=0,col=color[6],cex=cex+0.4,lwd=2)
points(ind+jit,y,pch=0,col=color[6],cex=cex+0.4,lwd=2)
}
if(include.xo) {
points(mxoloc$ind-jit,mxoloc$loc,pch=4,col="blue",lwd=2)
points(dxoloc$ind+jit,dxoloc$loc,pch=4,col="blue",lwd=2)
}
}
}
else {
if(horizontal) {
if(is.null(thexlim)) thexlim <- c(0, max(map))
if(is.null(theylim)) theylim <- c(n.ind+0.5,0.5)
plot(0,0,type="n",xlab="Location (cM)",ylab="Individual",
main=themain,
ylim=theylim,xlim=thexlim, yaxt="n")
segments(0, 1:n.ind, max(map), 1:n.ind)
if(use.id) axis(side=2, at=1:n.ind, labels=id)
else axis(side=2)
# AA genotypes
tind <- rep(1:n.ind,length(map));tind[is.na(data)] <- NA
ind <- tind; ind[!is.na(data) & data!=1] <- NA
x <- rep(map,rep(n.ind,length(map)))
points(x,ind,pch=21,col="black", bg=color[1],cex=cex)
# AB genotypes
ind <- tind; ind[!is.na(data) & data!=2] <- NA
if(type=="f2" || (type=="bc" && chr_type=="X"))
points(x,ind,pch=21,col="black", bg=color[2],cex=cex)
else points(x,ind,pch=21,col="black", bg=color[3],cex=cex)
if(type=="f2" || (type=="bc" && chr_type=="X")) {
# BB genotypes
ind <- tind; ind[!is.na(data) & data!=3] <- NA
points(x,ind,pch=21,col="black", bg=color[3],cex=cex)
}
if(type=="f2") {
# not BB (D in mapmaker/qtl) genotypes
ind <- tind; ind[!is.na(data) & data!=4] <- NA
points(x,ind,pch=21,col="black", bg=color[4],cex=cex)
# not AA (C in mapmaker/qtl) genotypes
ind <- tind; ind[!is.na(data) & data!=5] <- NA
points(x,ind,pch=21,col="black", bg=color[5],cex=cex)
}
# plot map
u <- par("usr")
segments(map,u[3],map,u[3]-1/2)
segments(map,u[4],map,u[4]+1/2)
if(any(errors != 0)) {
ind <- rep(1:n.ind,length(map));ind[errors!=1]<-NA
points(x,ind,pch=0,col=color[6],cex=cex+0.4,lwd=2)
}
if(include.xo) points(xoloc$loc,xoloc$ind,pch=4,col="blue",lwd=2)
}
else {
if(is.null(theylim)) theylim <- c(max(map), 0)
if(is.null(thexlim)) thexlim <- c(0.5,n.ind+0.5)
plot(0,0,type="n",ylab="Location (cM)",xlab="Individual",
main=themain,
xlim=thexlim,ylim=theylim, xaxt="n")
segments(1:n.ind,0,1:n.ind,max(map))
if(use.id) axis(side=1, at=1:n.ind, labels=id)
else axis(side=1)
# AA genotypes
tind <- rep(1:n.ind,length(map));tind[is.na(data)] <- NA
ind <- tind; ind[!is.na(data) & data!=1] <- NA
y <- rep(map,rep(n.ind,length(map)))
points(ind,y,pch=21,col="black", bg="white",cex=cex)
# AB genotypes
ind <- tind; ind[!is.na(data) & data!=2] <- NA
if(type=="f2" || (type=="bc" && chr_type=="X"))
points(ind,y,pch=21,col="black", bg=color[2],cex=cex)
else points(ind,y,pch=21,col="black", bg=color[3],cex=cex)
if(type=="f2" || (type=="bc" && chr_type=="X")) {
# BB genotypes
ind <- tind; ind[!is.na(data) & data!=3] <- NA
points(ind,y,pch=21,col="black", bg=color[3],cex=cex)
}
if(type=="f2") {
# not BB genotypes
ind <- tind; ind[!is.na(data) & data!=4] <- NA
points(ind,y,pch=21,col="black", bg=color[4],cex=cex)
# not AA genotypes
ind <- tind; ind[!is.na(data) & data!=5] <- NA
points(ind,y,pch=21,col="black", bg=color[5],cex=cex)
}
# plot map
u <- par("usr")
segments(u[1],map,(u[1]+1)/2,map)
segments(u[2],map,(n.ind+u[2])/2,map)
if(any(errors != 0)) {
ind <- rep(1:n.ind,length(map));ind[errors!=1]<-NA
points(ind,y,pch=0,col=color[6],cex=cex+0.4,lwd=2)
}
if(include.xo) points(xoloc$ind,xoloc$loc,pch=4,col="blue",lwd=2)
}
}
invisible()
}
######################################################################
#
# plotInfo: Plot the proportion of missing information in the
# genotype data.
#
######################################################################
plotInfo <-
function(x,chr,method=c("entropy","variance","both"), step=1,
off.end=0, error.prob=0.001,
map.function=c("haldane","kosambi","c-f","morgan"),
alternate.chrid=FALSE, fourwaycross=c("all", "AB", "CD"),
include.genofreq=FALSE, ...)
{
cross <- x
if(!inherits(cross, "cross"))
stop("Input should have class \"cross\".")
method <- match(match.arg(method),c("entropy","variance","both"))-1
map.function <- match.arg(map.function)
if(!missing(chr)) cross <- subset(cross,chr=chr)
n.chr <- nchr(cross)
results <- NULL
cross <- calc.genoprob(cross, step=step, error.prob=error.prob,
off.end=off.end, map.function=map.function)
gap <- 25
# 4-way cross: can consider just A/B or just C/D
fourwaycross <- match.arg(fourwaycross)
n.ind <- nind(cross)
if(include.genofreq) theprob <- NULL
for(i in 1:n.chr) {
n.gen <- dim(cross$geno[[i]]$prob)[3]
n.pos <- ncol(cross$geno[[i]]$prob)
# 4-way cross: can consider just A/B or just C/D
if(n.gen==4 && (fourwaycross!="all")) {
att <- attributes(cross$geno[[i]]$prob)
if(fourwaycross == "AB") {
cross$geno[[i]]$prob[,,1] <- cross$geno[[i]]$prob[,,1] + cross$geno[[i]]$prob[,,3]
cross$geno[[i]]$prob[,,2] <- cross$geno[[i]]$prob[,,2] + cross$geno[[i]]$prob[,,4]
}
else {
cross$geno[[i]]$prob[,,1] <- cross$geno[[i]]$prob[,,1] + cross$geno[[i]]$prob[,,2]
cross$geno[[i]]$prob[,,2] <- cross$geno[[i]]$prob[,,3] + cross$geno[[i]]$prob[,,4]
}
cross$geno[[i]]$prob <- cross$geno[[i]]$prob[,,1:2]
n.gen <- 2
for(j in seq(along=att))
if(names(att)[j] != "dim" && names(att)[j] != "dimnames")
attr(cross$geno[[i]]$prob, names(att)[j]) <- att[[j]]
}
# calculate information (between 0 and 1)
info <- .C("R_info",
as.integer(n.ind),
as.integer(n.pos),
as.integer(n.gen),
as.double(cross$geno[[i]]$prob),
info1=as.double(rep(0,n.pos)),
info2=as.double(rep(0,n.pos)),
as.integer(method),
PACKAGE="qtl")
if(method != 1) { # rescale entropy version
if(n.gen==3) maxent <- 1.5*log(2)
else maxent <- log(n.gen)
info$info1 <- -info$info1/maxent
}
if(method != 0) { # rescale variance version
maxvar <- c(0.25,0.5,1.25)[n.gen-1]
info$info2 <- info$info2/maxvar
}
# reconstruct map
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,]
z <- data.frame(chr=rep(names(cross$geno)[i],length(map)),
pos=as.numeric(map),
"Missing information"=info$info1,
"Missing information"=info$info2, stringsAsFactors=TRUE)
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(z) <- w
results <- rbind(results, z)
if(include.genofreq) {
p <- cross$geno[[i]]$prob
if(chrtype(cross$geno[[i]])=="X")
p <- reviseXdata(crosstype(cross), expandX="full", sexpgm=getsex(cross), prob=p,
cross.attr=attributes(cross))
p <- apply(p, 2:3, mean, na.rm=TRUE)
if(is.null(theprob))
theprob <- p
else {
m1 <- match(colnames(p), colnames(theprob))
m2 <- match(colnames(theprob), colnames(p))
if(!any(is.na(m1)) && !any(is.na(m2))) {
theprob <- rbind(theprob, p[,colnames(theprob)])
}
else { # some differences in column names
if(all(!is.na(m1))) { # need to add some new columns to p
noldcol <- ncol(p)
nnewcol <- sum(is.na(m2))
for(i in 1:nnewcol)
p <- cbind(p, 0)
colnames(p)[-(1:noldcol)] <- colnames(theprob)[is.na(m2)]
theprob <- rbind(theprob, p[,colnames(theprob)])
}
else if(all(!is.na(m2))) { # need to add some new columns to theprob
noldcol <- ncol(theprob)
nnewcol <- sum(is.na(m1))
for(i in 1:nnewcol)
theprob <- cbind(theprob, 0)
colnames(theprob)[-(1:noldcol)] <- colnames(p)[is.na(m1)]
theprob <- rbind(theprob, p[,colnames(theprob)])
}
else { # need to add some new columns to each
noldcol <- ncol(theprob)
nnewcol <- sum(is.na(m1))
oldcolnam <- colnames(theprob)
for(i in 1:nnewcol)
theprob <- cbind(theprob, 0)
colnames(theprob)[-(1:noldcol)] <- colnames(p)[is.na(m1)]
noldcol <- ncol(p)
nnewcol <- sum(is.na(m2))
for(i in 1:nnewcol)
p <- cbind(p, 0)
colnames(p)[-(1:noldcol)] <- oldcolnam[is.na(m2)]
theprob <- rbind(theprob, p[,colnames(theprob)])
}
}
}
} # end of if(include.genofreq)
}
colnames(results)[3:4] <- c("misinfo.entropy","misinfo.variance")
if(method==0) results <- results[,-4]
if(method==1) results <- results[,-3]
if(include.genofreq)
results <- cbind(results, theprob)
class(results) <- c("scanone","data.frame")
# check whether main was included as an argument
args <- list(...)
if("main" %in% names(args)) hasmain <- TRUE
else hasmain <- FALSE
# check whether gap was included as an argument
if(!("gap" %in% names(args))) {
if(method==0) {
if(hasmain)
plot.scanone(results,ylim=c(0,1),gap=gap,
alternate.chrid=alternate.chrid,...)
else
plot.scanone(results,ylim=c(0,1),gap=gap,
main="Missing information",
alternate.chrid=alternate.chrid,...)
}
else if(method==1) {
if(hasmain)
plot.scanone(results,ylim=c(0,1),gap=gap,
alternate.chrid=alternate.chrid,...)
else
plot.scanone(results,ylim=c(0,1),gap=gap,
main="Missing information",
alternate.chrid=alternate.chrid,...)
}
else if(method==2) {
if(hasmain)
plot.scanone(results,results,lodcolumn=1:2,ylim=c(0,1),gap=gap,
alternate.chrid=alternate.chrid,...)
else
plot.scanone(results,results,lodcolumn=1:2,ylim=c(0,1),gap=gap,
main="Missing information",
alternate.chrid=alternate.chrid,...)
}
}
else { # gap was included in ...
if(method==0) {
if(hasmain)
plot.scanone(results,ylim=c(0,1),
alternate.chrid=alternate.chrid,...)
else
plot.scanone(results,ylim=c(0,1),
main="Missing information",
alternate.chrid=alternate.chrid,...)
}
else if(method==1) {
if(hasmain)
plot.scanone(results,ylim=c(0,1),
alternate.chrid=alternate.chrid,...)
else
plot.scanone(results,ylim=c(0,1),
main="Missing information",
alternate.chrid=alternate.chrid,...)
}
else if(method==2) {
if(hasmain)
plot.scanone(results,results,lodcolumn=1:2,ylim=c(0,1),
alternate.chrid=alternate.chrid,...)
else
plot.scanone(results,results,lodcolumn=1:2,ylim=c(0,1),
main="Missing information",
alternate.chrid=alternate.chrid,...)
}
}
invisible(results)
}
# plot phenotypes against one or more markers
plotPXG <-
function(x, marker, pheno.col = 1, jitter = 1, infer = TRUE,
pch, ylab, main, col, ...)
{
cross <- x
if(!inherits(cross, "cross"))
stop("Input should have class \"cross\".")
type <- crosstype(cross)
if(LikePheVector(pheno.col, nind(cross), nphe(cross))) {
cross$pheno <- cbind(pheno.col, cross$pheno)
pheno.col <- 1
}
if(length(pheno.col) > 1) {
pheno.col <- pheno.col[1]
warning("plotPXG can take just one phenotype; only the first will be used")
}
if(is.character(pheno.col)) {
num <- find.pheno(cross, pheno.col)
if(is.na(num))
stop("Couldn't identify phenotype \"", pheno.col, "\"")
pheno.col <- num
}
if(pheno.col < 1 | pheno.col > nphe(cross))
stop("pheno.col values should be between 1 and the no. phenotypes")
if(!is.numeric(cross$pheno[,pheno.col]))
stop("phenotype \"", colnames(cross$pheno)[pheno.col], "\" is not numeric.")
if(missing(pch)) pch <- par("pch")
if(missing(ylab)) ylab <- colnames(cross$pheno)[pheno.col]
oldlas <- par("las")
on.exit(par(las = oldlas))
par(las = 1)
# find chromosomes containing the markers
o <- sapply(cross$geno, function(a, b) b %in% colnames(a$data),
marker)
if(length(marker)==1) o <- matrix(o,nrow=1)
if(!all(apply(o,1,any))) {
oo <- apply(o,1,any)
stop("Marker ", marker[!oo], " not found")
}
n.mark <- length(marker)
o <- apply(o, 1, which)
chr <- names(cross$geno)[o]
uchr <- unique(chr)
cross <- subset(cross, chr=uchr)
map <- pull.map(cross)
pos <- NULL
for(i in seq(length(chr))) pos[i] <- map[[chr[i]]][marker[i]]
chr_type <- sapply(cross$geno, chrtype)
names(chr_type) <- names(cross$geno)
chr_type <- chr_type[chr]
# if X chromosome and backcross or intercross, get sex/direction data
if(any(chr_type == "X") && (type == "bc" || type == "f2"))
sexpgm <- getsex(cross)
else sexpgm <- NULL
# number of possible genotypes
gen.names <- list()
for(i in seq(length(chr)))
gen.names[[i]] <- getgenonames(type, chr_type[i], "full", sexpgm, attributes(cross))
n.gen <- sapply(gen.names, length)
jitter <- jitter/10
if(any(n.gen == 2)) jitter <- jitter * 0.75
# function to determine whether genotype is fully known
tempf <-
function(x, type)
{
tmp <- is.na(x)
if(type=="f2") tmp[!is.na(x) & x>3] <- TRUE
if(type=="4way") tmp[!is.na(x) & x>4] <- TRUE
tmp
}
# if infer=TRUE, fill in genotype data by a single imputation
if(infer) {
which.missing <- tempf(cross$geno[[chr[1]]]$data[, marker[1]],type)
if(n.mark > 1)
for(i in 2:n.mark)
which.missing <- which.missing | tempf(cross$geno[[chr[i]]]$data[,marker[i]],type)
which.missing <- as.numeric(which.missing)
cross <- fill.geno(cross, method = "imp")
}
else which.missing <- rep(1,nind(cross))
# data to plot
x <- cross$geno[[chr[1]]]$data[, marker[1]]
if(n.mark > 1)
for(i in 2:n.mark)
x <- cbind(x, cross$geno[[chr[i]]]$data[, marker[i]])
else x <- as.matrix(x)
y <- cross$pheno[, pheno.col]
if(!infer) { # replace partially informative genotypes with NAs
if(type == "f2") x[x > 3] <- NA
if(type == "4way") x[x > 4] <- NA
if(sum(!is.na(x)) == 0)
stop("Can't use infer=FALSE as there are no fully informative genotypes")
}
# in case of X chromosome, recode some genotypes
if(any(chr_type == "X") && (type == "bc" || type == "f2")) {
ix = seq(n.mark)[chr_type == "X"]
for(i in ix)
x[, i] <- as.numeric(reviseXdata(type, "full", sexpgm,
geno = as.matrix(x[, i]),
cross.attr=attributes(cross)))
}
# save all of the data, returned invisibly
data <- as.data.frame(x, stringsAsFactors=TRUE)
names(data) <- marker
for(i in marker) data[[i]] <- ordered(data[[i]])
data$pheno <- y
data$inferred <- which.missing
# re-code the multi-marker genotypes
if(n.mark > 1) {
for(i in 2:n.mark)
x[, 1] <- n.gen[i] * (x[, 1] - 1) + x[, i]
}
x <- x[, 1]
observed <- sort(unique(x))
# amount of jitter
u <- runif(nind(cross), -jitter, jitter)
r <- (1 - 2 * jitter)/2
# genotype names
if(n.mark == 1)
gnames <- gen.names[[1]]
else {
gnames <- array(gen.names[[n.mark]], c(prod(n.gen), n.mark))
for(i in (n.mark - 1):1) {
tmpi <- rep(gen.names[[i]], rep(prod(n.gen[(i + 1):n.mark]),
n.gen[i]))
if(i > 1)
tmpi <- rep(tmpi, prod(n.gen[1:(i - 1)]))
gnames[, i] <- tmpi
}
gnames <- apply(gnames, 1, function(x) paste(x, collapse = "\n"))
}
# create plot
plot(x + u, y, xlab = "Genotype", ylab = ylab, type = "n",
main = "", xlim = c(1 - r + jitter, length(gnames) + r + jitter), xaxt = "n",
...)
# marker names at top
if(missing(main))
mtext(paste(marker, collapse = "\n"),
line=0.5, cex = ifelse(n.mark==1, 1.2, 0.8))
else
title(main=main)
abline(v = 1:prod(n.gen), col = "gray", lty = 3)
if(length(pch) == 1)
pch = rep(pch, length(x))
if(infer) {
points((x + u)[which.missing == 1], y[which.missing ==
1], col = "red", pch = pch[which.missing == 1])
points((x + u)[which.missing == 0], y[which.missing ==
0], pch = pch[which.missing == 0])
}
else points(x + u, y, pch = pch)
sux = sort(unique(x))
# add confidence intervals
me <- se <- array(NA, length(gnames))
me[sux] <- tapply(y, x, mean, na.rm = TRUE)
se[sux] <- tapply(y, x, function(a) sd(a, na.rm = TRUE)/sqrt(sum(!is.na(a))))
thecolors <- c("black", "blue", "red", "purple", "green", "orange")
if(missing(col)) {
col <- thecolors[1:n.gen[n.mark]]
if(n.gen[n.mark] == 3)
col <- c("blue", "purple", "red")
else if(n.gen[n.mark] == 2)
col <- c("blue", "red")
}
ng <- length(gnames)
segments(seq(ng) + jitter * 2, me, seq(ng) +
jitter * 4, me, lwd = 2, col = col)
segments(seq(ng) + jitter * 3, me - se, seq(ng) +
jitter * 3, me + se, lwd = 2, col = col)
segments(seq(ng) + jitter * 2.5, me - se, seq(ng) +
jitter * 3.5, me - se, lwd = 2, col = col)
segments(seq(ng) + jitter * 2.5, me + se, seq(ng) +
jitter * 3.5, me + se, lwd = 2, col = col)
# add genotypes below
u <- par("usr")
cxaxis <- par("cex.axis")
segments(seq(along=gnames), u[3], seq(along=gnames), u[3] - diff(u[3:4]) *
0.015, xpd = TRUE)
axis(side=1, at=seq(along=gnames), labels=gnames,
cex=ifelse(n.mark==1, cxaxis, cxaxis*0.8),
tick=FALSE, line = (length(marker)-1)/2)
invisible(data)
}
plotPheno <-
function(x, pheno.col=1, ...)
{
if(!inherits(x, "cross"))
stop("Input should have class \"cross\".")
if(LikePheVector(pheno.col, nind(x), nphe(x))) {
x$pheno <- cbind(pheno.col, x$pheno)
pheno.col <- 1
}
if(length(pheno.col) > 1) {
pheno.col <- pheno.col[1]
warning("Ignoring all but the first element in pheno.col.")
}
if(is.character(pheno.col)) {
num <- find.pheno(x, pheno.col)
if(is.na(num))
stop("Couldn't identify phenotype \"", pheno.col, "\"")
pheno.col <- num
}
if(pheno.col < 1 | pheno.col > nphe(x))
warning("pheno.col should be between 1 and ", nphe(x))
phe <- x$pheno[,pheno.col]
u <- length(unique(phe))
if(u==2 || (u < 10 && nind(x) > 50))
phe <- as.factor(phe)
plot_pheno_sub <-
function(phe, xlab=paste("phe", pheno.col),
main=colnames(x$pheno)[pheno.col], col="white",
breaks=ceiling(2*sqrt(nind(x))),
las=1,
...)
{
if(is.factor(phe)) {
barplot(table(phe), xlab=xlab, main=main, col=col, las=las, ...)
}
else {
phe <- as.numeric(phe)[1:nind(x)]
hist(phe, breaks = breaks,
xlab = xlab, main = main, las=las, ...)
}
}
plot_pheno_sub(phe, ...)
}
# end of plot.R
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.