I'd like to display the results so that one can see the "overall impact" of the factor as a problem, as well as get some idea of the breakdown of slows, severely slows and blocks. Some respondents didn't answer some questions
The data is in this form:
test <-read.csv(textConnection("
RespondentID,Bandwidth,Cycles
1,Slows research,No Impact
2,No Impact,Severely slows research
3,Blocks my research,No Impact
4,,No Impact
5,Slows research,No Impact
"))
In the first case I'd just like to look at counts of the answers for each factor (ie Bandwidth). I was thinking of a stacked bar graph for that (ie one bar for each question, height of the bar representing counts of the answers for each factor, sections of the bar colored by the answer). I can't actually get that working, although I think it's probably quite simple.
For the "overall impact" I thought I'd weight the answers so that No Impact = 0, Slows = 3, Severely Slows=7, Blocks = 10 (this is based on the relative ordering of how much the factor impacts people's research), so that the height of the bar is (count of answer * weight of answer) and the colored sections would again show the breakdown by the answer.
I'm pretty sure that the answer to this involves rearranging the data with melt, something like:
> testd <- melt(test,id="RespondentID", measures=c("Bandwidth","Cycles"))
> testd
RespondentID variable value
1 1 Bandwidth Slows research
2 2 Bandwidth No Impact
3 3 Bandwidth Blocks my research
4 4 Bandwidth
5 5 Bandwidth Slows research
6 1 Cycles No Impact
7 2 Cycles Severely slows research
8 3 Cycles No Impact
9 4 Cycles No Impact
10 5 Cycles No Impact
I tried:
ggplot(testd,aes(value,group=variable)) + geom_bar()
but that's not right :) I also tried:
ggplot(testd,aes(value,fill=variable)) + geom_bar() + facet_grid(variable ~ .)
which at least worked how I expected. The question is how to "stack" those colored sections on top of each other, then get rid of the facet ... I'd also like to drop respondents with no answer for a question (or perhaps replace that with No Answer (weight=0))
Any ideas would be appreciated; I'm having trouble thinking of the data in a form that ggplot likes. Perhaps people can think of a better way to represent the data than the charts I'm failing to make :)
Thanks,
James
I'm not sure what you want, but maybe:
ggplot(testd,aes(variable, fill = value)) + geom_bar()
For the weighting, do something like this:
weights <- c("Blocks my research" = 10, "No Impact" = 0, "Slows
research" = 3, "Severely slows research" = 7)
ggplot(testd,aes(variable, fill = value, weight = weights[value])) + geom_bar()
(that doesn't quite work, but you get the idea)
Hadley
> --
> You received this message because you are subscribed to the ggplot2 mailing list.
> To post to this group, send email to ggp...@googlegroups.com
> To unsubscribe from this group, send email to
> ggplot2+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/ggplot2
Here's what I have now (working with real data read from a URL). Hopefully you can see what I'm trying to communicate. Doing both the unweighted and the weighted, helps to see that overall there wasn't a lot of impact from these factors, but (with this weighting) for OSG answers) post-processing was the biggest problem, while Overall Computational cycles is the biggest problem.
Ideally I'd like to be able to:
1) move the legend to the top or bottom (at the moment that completely breaks things, see commented out legend.position)
2) Automatically order the bars according to their weighted order (highest to lowest top to bottom). I manually ordered them by specifying levels in the variable factor, but is there any way to get that order given the weights passed to weights?
btw, Melt rules :)
Thanks again,
James
library(ggplot2)
library(gdata)
dataBoth <- read.csv("http://freelancepropaganda.com/temp/BlockagesBoth.csv",na.strings="")
dataBoth <- NAToUnknown(dataBoth, unknown="No Answer")
dataBothm <- melt(dataBoth, id.vars="RespondentID")
# extract domain
dataBothm <- cbind(dataBothm, colsplit(dataBothm$variable, split="kk", names = c("domain","question")))
# remove old variable column (just for cleaness)
datadsub <- dataBothm[,-2]
#Order the levels
datadsub$value <- factor(datadsub$value,levels=c("No Answer", "No impact", "Slows research", "Severely slows research", "Blocks my research"))
# manually order the questions
datadsub$question <- factor(datadsub$question, levels=c("Concern.about.security.privacy.of.my.analysis.software","Concern.about.security.privacy.of.data","Explaining.my.needs.to.technical.people","Insufficient.bandwidth.for.data","Adapting.existing.software.to.new.computing.resource","Insufficient.computation.cycles","Collecting.and.post.processing.results.of.computation"))
weightfn <- function(x) {
xchar <- as.character(x)
switch(xchar,
"Blocks my research" = 10,
"Severely slows research" = 7,
"Slows research" = 3,
"No impact" = 0,
"No Answer" = 0)
}
datadsub$weighted_value <- sapply(datadsub$value, weightfn)
colorMap <- c("Blocks my research"="grey30","Severely slows research"="grey50", "Slows research"="grey60", "No impact" = "grey70", "No Answer" = "grey80")
# Plot to pdf
p <- ggplot(datadsub,aes(question, fill = value)) + facet_grid(. ~ domain)
p <- p + geom_bar() + coord_flip() + scale_y_continuous("Unweighted Answer Count") + xlab("")
p <- p + scale_fill_manual("Impact", values = colorMap) + scale_x_discrete("")
ggsave("~/Desktop/unweighted.pdf", p, width=14,height=4) #+ opts(legend.position="top")
# Plot weighted
p <- ggplot(datadsub,aes(question, fill = value, weight = weighted_value))
p <- p + geom_bar() + scale_y_continuous("Weighted Impact (Block=10, Severe=7, Slows=4, No Impact | No Answer=0)") + scale_x_discrete("")
p <- p + scale_fill_manual("Impact", values = colorMap)
p <- p + coord_flip() + facet_grid(. ~ domain)
ggsave("~/Desktop/weighted.pdf", p, width=14,height=4)
Yes, a known bug and high on my to do list.
> 2) Automatically order the bars according to their weighted order (highest to lowest top to bottom). I manually ordered them by specifying levels in the variable factor, but is there any way to get that order given the weights passed to weights?
order = weights should work (or maybe order = -weights).
Hadley