getcolors <- function(cols, n) { if (n > length(cols)) { cols <- c(cols, adjustcolor(cols, alpha.f=0.8)) } return(cols[1:n]) } remove__ <- function(s, patten='__') { if (grepl(patten, s)) { s <- strsplit(s, patten)[[1]][2] } return(s) } select <- function(data, abundance=0, topnum=0, firstnum=0, minsample=0, sort=1, unclass=TRUE, merge=FALSE, other=TRUE, per=TRUE, remove=TRUE) { data <- data[rowSums(data) > 0, , drop=F] if (nrow(data) == 1) { if (per) {data[1,] <- 100} return(data) } if (max(data) > 100) { abu <- apply(data, 2, function(x) x/sum(x)*100) } else { abu <- data } II <- rep(0, nrow(abu)) if (abundance != 0) { for (i in 1:nrow(abu)) { if (max((abu[i,]) > abundance)){ II[i] <- 1 } } } else if (topnum != 0) { rowSum <- rowSums(abu) index <- rev(order(rowSum)) if (nrow(abu) > topnum) { II[index[1:topnum]] <- 1 } else { II <- rep(1, nrow(abu)) } } else if (firstnum != 0) { for (i in 1:ncol(abu)) { index <- rev(order(abu[, i])) if (nrow(abu) > firstnum) { II[index[1:firstnum]] <- 1 } else { II <- rep(1, nrow(abu)) } } } else if (minsample != 0) { count <- ifelse(minsample > 1, minsample, minsample*ncol(abu)) for (i in 1:nrow(abu)) { if (length(which(abu[1,]>0)) > minsample){ II[i] <- 1 } } } else { II <- rep(1, nrow(abu)) } selectabu <- abu[which(II==1), , drop=F] if (sort != 0) { rowSum <- rowSums(selectabu) index <- order(rowSum) if (sort == 1) { selectabu <- selectabu[rev(index), , drop=F] } else { selectabu <- selectabu[index, , drop=F] } } selectdata <- data[rownames(selectabu), , drop=F] usedata <- selectdata if (unclass) { unclass <- sapply(rownames(selectdata), function(x) grepl('unclassified', x, perl=T)) unclassdata <- selectdata[unclass, , drop=F] classdata <- selectdata[!unclass, , drop=F] if (sum(unclass) > 0) { if (merge) { Unclassified <- colSums(unclassdata) Unclassified <- t(data.frame(Unclassified)) usedata <- rbind(classdata, Unclassified) } else { usedata <- rbind(classdata, unclassdata) } } } resdata <- usedata if (other) { if (length(which(II==0)) > 1) { Other <- colSums(data[which(II==0), , drop=F]) Other <- t(data.frame(Other)) resdata <- rbind(usedata, Other) } else if (length(which(II==0)) == 1) { resdata <- rbind(usedata, data[which(II==0), , drop=F]) } } if (per & (max(data) > 100)) { if (nrow(resdata) > 1) { #resdata <- apply(resdata, 2, function(x) x/sum(x)*100) resdata <- t(t(resdata) / colSums(data) * 100) } else { resdata[1,] <- 100 } } if (remove){ rownames(resdata) <- sapply(rownames(resdata), remove__) } return(resdata) } data <- read.table('genus_count.xls', header=T, sep='\t', check.names=F, row.names=1) name <- 'genus' palette <- c('#CA0000','#0087FF','#00BA1D','#CF00FF','#00DBE2','#FFAF00','#0017F4','#006012','#6F1A1A','#B5CF00','#009E73','#F0E442','#D55E00','#CC79A7','#FF8A8A','#AA6400','#50008A','#00FF58','#E175FF','#FFCC99','#009999','#CC0066','#C0C0C0','#666600','#505050','#56B4E9','#0072B2','#33FF33','#99004c','#CCFF99','#660066','#9370DB','#D8BFD8','#BC8F8F','#2F4F4F','#FF6347','#877878','#CD5C5C','#FF0000','#00FF00','#000080','#0D7339','#3D90D9','#D98236','#DF514F','#8CCDA3','#F5E2D7','#FACBBE','#EA4885','#E69F00') #sangon 默认配色 abundance <- 1 topnum <- 0 firstnum <- 0 minsample <- 0 sort <- 1 unclass <- TRUE merge <- FALSE other <- TRUE per <- TRUE remove <- TRUE xlab <- '' ylab <- 'Relative Abundance (%)' title <- '' plotdata <- select(data, abundance, topnum, firstnum, minsample, sort, unclass, merge, other, per, remove) write.table(plotdata, paste0(name, '.xls'), sep='\t', col.names=NA, quote=F) left <- ceiling(ncol(plotdata)/10) + 2 right <- ceiling(nrow(plotdata)/30) right <- ifelse(max(nchar(rownames(plotdata)))>10, 2*right, 1.2*right) layout(matrix(c(1, 2), 1), c(left, right)) par(mar=c(4, 3, 2, 0), mgp=c(1.7, 0.7, 0)) if ('Other' %in% rownames(plotdata)) { cols <- c(getcolors(palette, nrow(plotdata)-1), 'grey') } else { cols <- getcolors(palette, nrow(plotdata)) } bar <- barplot(as.matrix(plotdata), xlab=xlab, ylab=ylab, xaxt='n', yaxt='n', col=cols, cex.lab=1, main=title) text(bar, par('usr')[3], labels=colnames(plotdata), cex=ifelse(ncol(plotdata)>30,0.6,0.8), srt=45, adj=c(1, 1), xpd=NA) axis(2, las=2, cex.axis=.8) par(mar=c(1, 1, 1, 0)) plot.new() legend('left', col=cols, legend=rownames(plotdata), pch=15, bty='n', cex=.6, text.font=3, ncol=ceiling(nrow(plotdata)/40))