[R] Generating a Special Histogram

David L Carlson dcarlson at tamu.edu
Thu Jan 5 21:49:06 CET 2017

Here's a different approach using barplot() to draw the boxes. The first line in the function sorts the values so that they are printed from lowest to highest on the histogram. If you want them in the original sequence, comment this line out. It also assumes you want intervals of 10:

wgt <- round(rnorm(45, 170, 15))

boxhist <- function(x) {
     x <- sort(x)
     obs <- 1:length(x)
     low <- floor(min(x/10))*10
     high <- ceiling(max(x/10))*10
     grp <- cut(x, breaks=c(seq(low, high, by=10)), include.lowest=TRUE)
     mat <- table(obs, grp)
     cols <- ncol(mat)
     barplot(mat, space=0, col="lightblue", xaxt="n")
     axis(1, 0:cols, seq(low, high, by=10))
     mat <- apply(mat, 2, cumsum) * mat
     xval <- apply(mat, 1, function(x) which(x > 0))
     yval <- apply(mat, 1, max)
     text(xval-.5, yval-.5, x)


David L Carlson
Department of Anthropology
Texas A&M University
College Station, TX 77840-4352

-----Original Message-----
From: R-help [mailto:r-help-bounces at r-project.org] On Behalf Of Duncan Murdoch
Sent: Thursday, January 5, 2017 10:47 AM
To: Dan Abner; r-help at r-project.org
Subject: Re: [R] Generating a Special Histogram

On 05/01/2017 11:01 AM, Dan Abner wrote:
> Hi all,
> Is anyone aware of a package, function, or general R trick that would make
> generating histograms like the one in the attachment easy in R (i.e.,
> without manually drawing each individual horizontal line and specifying the
> coordinates for a textbox for each number)?
> I need to make ~12 of these for different samples of n=25, so the manual
> approach would be very painful...

You can write a function to do this pretty easily.  hist(..., 
plot=FALSE) does all the calculations for you; you just need to write 
the loop to draw the boxes.  For example,

myhist <- function(x) {
   histvals <- hist(x, plot = FALSE)
   with(histvals, {
     plot(range(breaks), range(c(0, counts)), type = "n")

     for (i in seq_along(histvals$counts)) {
       keep <- (breaks[i] < x & x <= breaks[i+1]) |
               (i == 1 & x == breaks[1])
       vals <- x[keep]
       for (j in seq_along(vals)) {
         rect(breaks[i], j-1, breaks[i+1], j)
         text(mids[i], j-0.5, vals[j])

x <- round(rnorm(20, mean=166, sd=4))

Duncan Murdoch

R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: BoxHist.png
Type: image/png
Size: 8407 bytes
Desc: BoxHist.png
URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20170105/c6213613/attachment.png>

More information about the R-help mailing list