Bull charts

A colleague of mine needs to sketch 101 bull's eyes. This is not her idea. Instead of having a slave in Excel, or God knows what it does, I suggested making them in R; mapping the line plot to polar coordinates to make bulls-eyes is wind at ggplot2

.

I ran into a problem, however: the data is already aggregated, so Hadley's example here doesn't work for me. I could expand the abacus into factor to do this, but I feel like there is a better way - somehow tell geom_bar how to read the data.

The data looks like this:

    Zoo Animals Bears Polar Bears
1 Omaha      50    10           3

      

I will make a plot for each zoo, but this part I can handle.

and here it is dput

:

structure(list(Zoo = "Omaha", Animals = "50", Bears = "10", `Polar Bears` = "3"), .Names = c("Zoo", 
"Animals", "Bears", "Polar Bears"), row.names = c(NA, -1L), class = "data.frame")

      

Note: It is important that animals> = bears> = polar bears. Also, she's leaving town, so I can't just get the raw data from her (if there was a large file anyway).

+2


source to share


3 answers


The way to do this without disaggregating is to use stat="identity"

in geom_bar

.

This helps to create a data frame containing numeric values, not character strings:

dat <- data.frame(Zoo = "Omaha",
               Animals = 50, Bears = 10, `Polar Bears` = 3)

      

We need reshape2::melt

to set up the data correctly:



library(reshape2)
d3 <- melt(dat,id.var=1)

      

Now create a plot (identical to the other answer):

library(ggplot2)
ggplot(d3, aes(x = variable, y = value)) +
    geom_bar(width = 1, colour = "black",stat="identity") +
    coord_polar()

      

+1


source


While waiting for a better answer, I figured I should post the (suboptimal) solution you mentioned. dat

is the structure included in your question.



d <- data.frame(animal=factor(sapply(list(dat[2:length(dat)]),
                function(x) rep(names(x),x))))
cxc <- ggplot(d, aes(x = animal)) +  geom_bar(width = 1, colour = "black") 
cxc + coord_polar() 

      

+3


source


You can use inverse.rle

to recreate the data,

dd = list(lengths = unlist(dat[-1]), values = names(dat)[-1])
class(dd) = "rle"
inverse.rle(dd)

      

If you have multiple Zoos (rows) you can try

l = plyr::dlply(dat, "Zoo", function(z)  
      structure(list(lengths = unlist(z[-1]), values = names(z)[-1]), class = "rle"))

reshape2::melt(llply(l, inverse.rle))

      

+2


source







All Articles