4

enter image description hereI'm trying to create a bar graph using ggplot2 to show the occurrence of different consonants in some language data. For most subjects there is only one timepoint sampled, but for some of the subjects there are two timepoints. The subjects are grouped into two different groups for comparison, and their consonant production is grouped by type - a phonetic variable in my data.

I want to show the consonants produced by each subject in a stacked bar, and then have data from the speakers who were recorded twice show next to each other on the x axis. At the moment, ggplot is aggregating this data. I don't want to facet the data into two different plots.

 exampledata <- tribble(~subject, ~group, ~time, ~consonant, ~type,  ~n,
     "1", "A", 1, "p", F, 10,
     "1", "A", 1, "t", T, 12,
     "1", "A", 1, "k", T, 50,
     "2", "A", 1, "p", T, 0,
     "2", "A", 1, "t", T, 45,
     "2", "A", 1, "k", F, 23,
     "2", "A", 2, "p", F, 2,
     "2", "A", 2, "t", T, 34,
     "2", "A", 2, "k", T, 56,
     "3", "B", 1, "p", F, 12,
     "3", "B", 1, "t", T, 13,
     "3", "B", 1, "k", F, 50,
     "4", "A", 1, "p", T, 10,
     "4", "A", 1, "t", F, 12,
     "4", "A", 1, "k", T, 50,
     "5", "B", 1, "p", T, 0,
     "5", "B", 1, "t", T, 24,
     "5", "B", 1, "k", F, 3,
     "5", "B", 2, "p", F, 23,
     "5", "B", 2, "t", F, 12,
     "5", "B", 2, "k", T, 7,
     "6", "A", 1, "p", F, 52,
     "6", "A", 1, "t", F, 12,
     "6", "A", 1, "k", T, 64
     )

I'm currently using the following code, which generates the attached figure:

 plot1 <- ggplot(data=exampledata, aes(x=subject, y=n, fill=type, colour = group)) +
   geom_bar(stat="identity") +
   scale_fill_manual(values=c("gray97", "gray87")) +
   scale_colour_manual(values = c("royalblue", "navyblue")) +
   theme_bw()
 plot(plot1)
 [![example bar plot][1]][1]

So all I want to do now is somehow create an extra grouping variable that shows time bars side by side.

4 Answers 4

2

You can try to work with a facet but removing the faced-like shape

ggplot(exampledata, aes(x= time, y=n, fill=type))  +  
  geom_col() +
  facet_grid(~subject, scales = "free_x", switch = "x") + 
  xlab("subject") + 
  theme_bw() + 
  theme(axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        panel.border =element_blank(),
        strip.background = element_blank())

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

I was worried that this would look too full-on as I have a lot of subjects in my real dataset, but it looks great! Thank you!
2

Is that what you want?

plot1 <- ggplot(data=exampledata, aes(x=subject, y=n, fill=type, colour = group, group = time)) +
  geom_bar(stat="identity", position = 'dodge') +
  scale_fill_manual(values=c("gray97", "gray87")) +
  scale_colour_manual(values = c("royalblue", "navyblue")) +
  theme_bw()[![enter image description here][1]][1]

enter image description here

2 Comments

The plot looks wrong, right? The FALSE value of subject one is missing.
This is almost it but as @Jimbou says, the numbers don't stack correctly
2

In @JAQuent's response, although elegante, the stacking is not preserved. I propose this:

exampledata$interaction <- factor(interaction(exampledata$subject, exampledata$time),
                                  levels = sprintf("%d.%d", sort(rep(1:6, 2)), rep(1:2, 6)))

plot1 <- ggplot(data=exampledata, aes(x=interaction, y=n, fill=type, colour = group)) +
  geom_bar(aes(group = subject), stat="identity") +
  scale_fill_manual(values=c("gray97", "gray87")) +
  scale_colour_manual(values = c("royalblue", "navyblue")) +
  theme_bw()
plot(plot1)

enter image description here

Comments

1

It is a little bit of a hack, but this should do exactly what you want.

First your data needs to contain zeros for all combinations of subject, time, group and type. Like this:

exampledata <- tribble(~subject, ~group, ~time, ~consonant, ~type,  ~n,
                       "1", "A", 1, "p", F, 10,
                       "1", "A", 1, "t", T, 12,
                       "1", "A", 1, "k", T, 50,
                       "1", "A", 2, "p", F, 0,
                       "1", "A", 2, "t", T, 0,
                       "1", "A", 2, "k", T, 0,
                       "2", "A", 1, "p", T, 0,
                       "2", "A", 1, "t", T, 45,
                       "2", "A", 1, "k", F, 23,
                       "2", "A", 2, "p", F, 2,
                       "2", "A", 2, "t", T, 34,
                       "2", "A", 2, "k", T, 56,
                       "3", "B", 1, "p", F, 12,
                       "3", "B", 1, "t", T, 13,
                       "3", "B", 1, "k", F, 50,
                       "3", "B", 2, "p", F, 0,
                       "3", "B", 2, "t", T, 0,
                       "3", "B", 2, "k", F, 0,
                       "4", "A", 1, "p", T, 10,
                       "4", "A", 1, "t", F, 12,
                       "4", "A", 1, "k", T, 50,
                       "4", "A", 2, "p", T, 0,
                       "4", "A", 2, "t", F, 0,
                       "4", "A", 2, "k", T, 0,
                       "5", "B", 1, "p", T, 0,
                       "5", "B", 1, "t", T, 24,
                       "5", "B", 1, "k", F, 3,
                       "5", "B", 2, "p", F, 23,
                       "5", "B", 2, "t", F, 12,
                       "5", "B", 2, "k", T, 7,
                       "6", "A", 1, "p", F, 52,
                       "6", "A", 1, "t", F, 12,
                       "6", "A", 1, "k", T, 64,
                       "6", "A", 2, "p", F, 0,
                       "6", "A", 2, "t", F, 0,
                       "6", "A", 2, "k", T, 0
) 

Then you basically draw two bar charts. Normally you would offset each with position_nudge to left and right to have to bars per subject next to each other. However, since the position argument is already taken ("stacked") the hack is to turn subject into a numeric variable, nudge directly with as.numeric(subject) - 0.125 and as.numeric(subject) + 0.125 and then format the x axis accordingly so that noone notices.

ggplot(exampledata,
       aes(fill = type, colour = group)) +
    geom_col(
        data = subset(exampledata, time == 1),
        aes(x = as.numeric(subject) - 0.125, y = n),
        width = 0.25
    ) +
    geom_col(
        data = subset(exampledata, time == 2),
        aes(x = as.numeric(subject) + 0.125, y = n),
        width = 0.25
    ) +
    scale_fill_manual(values=c("gray97", "gray87")) +
    scale_colour_manual(values = c("royalblue", "navyblue")) +
    scale_x_continuous(limits = c(0.5, 6.5),
                       breaks = (c(1:6))) +
    xlab("subjects")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.