Hello people, A while back I wanted to plot boxplots with interactions that will have a dot for the mean of the sample + bars for the SE. After searching for some code, I found something that did it for one level, but couldn't find something that will allow for interactions the way the original boxplot does.
After playing with the original code, I found a way for allowing the boxplot code to introduce interactions to it. The price for that was that I was forced to use a little different syntax for the function then that of the original boxplot. In order to use the function, one must use lists for the function input arguments, and until now I didn't find a way for doing the same task from a formula input. So for example, the original boxplot will be written like this: boxplot(y ~ A*B) Where as my function will look like this: boxplot.2(y , list(A,B) ) In this e-mail I am giving away the code for: 1) helping out others searching for this solution. and 2) in hope to have more experienced R programmers come by and improve on this code (by, for example, removing the for loop in it, or allowing to use a formula instead of a list input) Here is the code: boxplot.2 <- function(fo.head, list.fo.tail = list(1), print.mean = T, plot.CI = T, add.mean.sd.to.boxplot.names = T, plot.round.factor = 2 ,...) { require(gplots) tmp <- split(fo.head , list.fo.tail) means <- sapply(tmp, mean) stdev <- sqrt(sapply(tmp, var)) #IS right - because of the sqrt !!! <- sqrt(sapply(tmp, var)) # was var, I changed it to sd n <- sapply(tmp,length) ciw <- qt(0.975, n-1) * stdev / sqrt(n) old.names = attributes(tmp)$names length.of.names = length(old.names) new.names = as.list(old.names) for(i in c(1:length.of.names)) { new.names[[i]] <- paste(old.names[i], " (", round(means[i],plot.round.factor) ,",", round(ciw[i],plot.round.factor) ,")", sep = "") } if(add.mean.sd.to.boxplot.names) { if(length(list.fo.tail) == 1) { sub.text = paste("mean:", round(means,3), "(SE:",round(ciw,3), " ; N:" ,n, ")") boxplot(tmp, xlab = sub.text, cex.axis = min(1, mean(c(1,12/ max(nchar(new.names)) )) ), ...) } else { boxplot(tmp, names = new.names, cex.axis = min(1, mean(c(1,12/ max(nchar(new.names)) )) ), ...) } } else { boxplot(tmp, ...) } # else - make boxplot without them # adding the points and the bars points(means, col = 'red', pch = 19) if(require(gplots) & plot.CI) { plotCI(x=means, uiw=ciw, col="white", barcol="blue", xaxt="n" , add = T) } if(print.mean) { small.mean.and.se.table <- rbind(round(means,3),round(ciw,3), n) rownames(small.mean.and.se.table) <- c("means:", "SE's:", "N") print(t(small.mean.and.se.table)) } } # <-- end boxplot3 # Here is a small example: data(mtcars) head(mtcars) attach(mtcars) boxplot.2(mpg , list(round(wt), am) , data = mtcars, las = 2) Hope this will benefit others, and also hope that others will improve on this code and give it back to the community, Tal galili -- ---------------------------------------------- My contact information: Tal Galili Phone number: 972-50-3373767 FaceBook: Tal Galili My Blogs: http://www.r-statistics.com/ http://www.talgalili.com http://www.biostatistics.co.il [[alternative HTML version deleted]] ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.