Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
290 views
in Technique[技术] by (71.8m points)

r - Multiple histograms in ggplot2

Here is a short part of my data:

dat <-structure(list(sex = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("male", 
"female"), class = "factor"), A = c(1, 2, 0, 2, 1, 2, 2, 0, 2, 
0, 1, 2, 2, 0, 0, 2, 0, 0, 0, 2), B = c(0, 0, 0, 0, 0, 2, 0, 
0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0), C = c(1, 2, 1, 0, 0, 
2, 1, 1, 0, 1, 1, 0, 1, 2, 1, 2, 0, 2, 1, 2), D = c(2, 2, 0, 
2, 2, 2, 1, 0, 1, 1, 1, 0, 1, 2, 0, 0, 1, 1, 1, 0), E = c(0, 
0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 2, 2), F = c(2, 
2, 1, 2, 1, 2, 2, 0, 1, 2, 0, 1, 2, 2, 0, 1, 2, 2, 2, 2)), .Names = c("sex", 
"A", "B", "C", "D", "E", "F"), variable.labels = structure(c("sex", 
"zenuwac", "panieke", "gespann", "rustelo", "angstig", "onzeker"
), .Names = c("sex", "anx01", "anx02", "anx03", "anx04", "anx05", 
"anx06")), codepage = 20127L, row.names = c(NA, 20L), class = "data.frame")

A data frame with scores of males and females on six 3-point variables. Now I want to create a plot which shows the histograms of the scores of each variable of both males and females in a grid. For example, I can do:

layout(matrix(1:12,6,2,byrow=TRUE))
par(mar=c(2,1,2,1))
for (i in 1:6) for (s in c("male","female")) hist(dat[dat$sex==s,i+1],main=paste("item",names(dat)[i+1],s))

which results in:

Histogram with base R graphics

I could make this look better but I am more interested in learning how to use ggplot2. So my question is, how do I create a pretty version of this using ggplot2? One thing I got working is:

library("ggplot2")
grid.newpage()
pushViewport(viewport(layout = grid.layout(6, 2)))   
for (s in 1:2)
{
    for (i in 1:6)
    {
        p <- qplot(dat[dat$sex==c("male","female")[s],i+1]+0.5, geom="histogram", binwidth=1)
        print(p, vp = viewport(layout.pos.row = i, layout.pos.col = s))
    }
}

But I guess there is a much easier way to do this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can try grid.arrange() from the gridExtra package; i.e., store your plots in a list (say qplt), and use

do.call(grid.arrange, qplt)

Other ideas: use facetting within ggplot2 (sex*variable), by considering a data.frame (use melt).

As a sidenote, it would be better to use stacked barchart or Cleveland's dotplot for displaying items response frequencies, IMO. (I gave some ideas on CrossValidated.)


For the sake of completeness, here are some implementation ideas:

# simple barchart
ggplot(melt(dat), aes(x=as.factor(value), fill=as.factor(value))) + 
  geom_bar() + facet_grid (variable ~ sex) + xlab("") + coord_flip() + 
  scale_fill_discrete("Response")

enter image description here

my.df <- ddply(melt(dat), c("sex","variable"), summarize, 
               count=table(value))
my.df$resp <- gl(3, 1, length=nrow(my.df), labels=0:2)

# stacked barchart
ggplot(my.df, aes(x=variable, y=count, fill=resp)) + 
  geom_bar() + facet_wrap(~sex) + coord_flip()

enter image description here

# dotplot
ggplot(my.df, aes(x=count, y=resp, colour=sex)) + geom_point() + 
  facet_wrap(~ variable)

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...