[R] Barplot+Table

Marc Schwartz marc_schwartz at me.com
Fri Sep 11 23:31:10 CEST 2009


On Sep 11, 2009, at 1:20 PM, Andy Choens wrote:

> I am trying to automate a report that my company does every couple  
> of years
> for the state of Maine. In the past we have used SPSS to run the  
> data and then
> used complicated Excel template to make the tables/graphics which we  
> then
> imported into Word. Since there are 256 tables/graphics for this  
> report, this
> work flow is a little painful. I would like to automate the process  
> and I think
> I can do so with odfWeave and R, but I've run into a problem. I  
> can't seem to
> get the output from R to look like what we have used in the past.  
> Here's an
> example of what I need it to look like (sorry for the long URL)
>
> http://1.bp.blogspot.com/_TRRvdLHNnE8/SqpP5gFG3DI/AAAAAAAABgY/09x-
> LoLtfTI/s1600-h/example+graphic.png
>
> My boss is open to using another tool (R) to get the work done but  
> my final
> output needs to look, more or less, like what we did last time.
>
> I can make a table and I can make a bar graph that, essentially gets  
> me where
> I want to go (I can handle the tweaking) but I don't know how to put  
> them
> together and make things line up, as in my example (URL).
>
> I have looked at iplot, ggplot, lattice, etc. I will confess that my  
> knowledge
> of R's graphical capabilities leaves a lot to be desired (as I am  
> proving
> today) but I really can not find an example or feature that seems to  
> do what I
> am trying to do. I am more or less satisfied with the plot, but I  
> really would
> like to line up the table with the graphics, which is why I don't  
> just put a
> table under the graph via odfweave.
>
> Here's what I have thus far:
>
> ###################################################
> # These numbers are just BS I made up.
> counties <-
> c 
> ("County1 
> ","County2 
> ","County1 
> ","County2 
> ","County1 
> ","County2 
> ","County1 
> ","County2 
> ","County1 
> ","County2 
> ","County1 
> ","County2 
> ","County1 
> ","County2 
> ","County1 
> ","County2 
> ","County1 
> ","County2 
> ","County1","County2","County1","County2","County1","County2")
>
> gender <- c("Male", "Male","Male", "Male", "Male", "Female","Female",
> "Female","Male", "Male","Male", "Female","Male", "Female","Male",
> "Female","Male", "Female","Female", "Female","Male",  
> "Female","Male", "Male")
>
> weight <- c(1,2,1,2,1,2,2,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2)
>
> example.table<-xtabs(weight~counties+gender)
> barplot(prop.table(example.table,1),beside=T)
> ###################################################
>
> I am open to using any of the various graphics systems provided in  
> R. I am
> willing/capable of learning and in fact, I want to learn how to do  
> this but I
> can't even figure out which system I should spend my time learning  
> more about
> and I don't have time to become an expert with all of them.
>
> Thank you.


Using the data that is in the online plot rather than the above, here  
is a first go. Note that I am not drawing the background grid in the  
barplot or the lines for table below it. These could be added if you  
really need them.


# Create data
MyData <- matrix(c(57.1, 52.3, 13.5, 13.9, 7.9, 8.8, 5.4, 5.6,
                    16.1, 19.4),
                  nrow = 2)

# Note that by using '\n' in the text, the label will be plotted on
# two lines. '\n' is a newline character
colnames(MyData) <- c("0 occasions", "1-2 Occasions", "3-5 Occasions",
                       "6-9 Occasions", "10 or more\nOccasions")

rownames(MyData) <- c("Androscoggin", "Maine")


 > MyData
              0 occasions 1-2 Occasions 3-5 Occasions 6-9 Occasions
Androscoggin        57.1          13.5           7.9           5.4
Maine               52.3          13.9           8.8           5.6
              10 or more\nOccasions
Androscoggin                  16.1
Maine                         19.4




# Set graph margins to make room for labels
# See ?par
par(mar = c(5, 8, 4, 1))


# Set colors
MyCols <- c("black", "grey80")


# Set label size
MyCex = 0.75


# Set lines for table data
MyLines <- 2:3


# do barplot, getting bar midpoints in 'mp'
# See ?barplot
mp <- barplot(MyData, beside = TRUE, ylim = c(0, 100),
               yaxt = "n", cex.names = MyCex, col = MyCols)


# mp contains the following. The mean of each column
# is the horizontal center of each pair of bars
 > mp
      [,1] [,2] [,3] [,4] [,5]
[1,]  1.5  4.5  7.5 10.5 13.5
[2,]  2.5  5.5  8.5 11.5 14.5


# Put a box around it
box()


# Draw y axis tick marks and labels
axis(2, at = seq(0, 100, 10), las = 1)


# Draw values below plot
# Use the values of 'mp' from above.
# See ?mtext
mtext(side = 1, text = MyData,
       at = rep(colMeans(mp), each = nrow(MyData)),
       line = MyLines, cex = MyCex)


# Get min value for the x axis. See ?par 'usr'
min.x <- par("usr")[1]


# Draw categories using mtext
# See ?strwidth to get the length of the labels in
# user coordinates, which is then used for 'at'
# Setting 'adj = 0' left justifies the text
mtext(side = 1, line = MyLines, text = rownames(MyData),
       at = min.x - max(strwidth(rownames(MyData), cex = MyCex)),
       adj = 0, cex = MyCex)


# Draw the colored boxes
# Same here for strheight as with strwidth above
# Part of this is getting the vertical positioning to align with
# the text and the horizontal position at the beginning of the labels
# Note that we have to set 'xpd = TRUE' so that the points are drawn
# outside the plotting region. See ?par and 'xpd'
# We just need a single capital letter for strheight() to get the value

VertOff <- strheight("X", cex = MyCex) * c(6, 8)
HorizOff <- min.x - (0.85 * max(strwidth(rownames(MyData))))

points(rep(HorizOff, nrow(MyData)),
        par("usr")[3] - VertOff, bg = MyCols, pch = 22,
        xpd = TRUE, cex = MyCex)



HTH,

Marc Schwartz




More information about the R-help mailing list