0

I have a data set like this

df <- data.frame(ID=c("10","11","14","15","16","18","3","5","6","8","9","n"),
                 A=c("C","U","U","C","C","C","U","C","U","U","C","U"),
                 B=c("P","P","C","P","C","C","C","P","C","P","C","P"),
                 N=c(7,2,8,6,2,3,7,4,9,5,4,4))

ID is the identification number of each row. N is the value. A and B are two categories. I would like to create a bar plot or similar to compare N based on A and B category.

Here is my code:

ggplot(data=df,aes(x=ID,y=N,fill=A)) +
  geom_col(position="dodge")+
  facet_wrap(~B)

What I got is this: enter image description here

Here I hope I can put the same color together in each "C" and "P" category, and I would like to delete the empty columns from the graph, for example ID-10 in "C" cateogory.

I probably did not use the most appropriate way to make this figure, but this is what I can think of right now. If you have better ways to create the figure, could you help me please? Thank you!

XM_Z
  • 41
  • 1
  • 7
  • 1
    For getting rid of the extra values that aren't present in a facet panel you can use the `scales` argument in `facet_wrap()` to allow the x axis to differ between panels via `scales = "free_x"`. – aosmith Jun 24 '21 at 18:30
  • Thank you @aosmith! The `scales` argument helps! – XM_Z Jun 24 '21 at 18:48

1 Answers1

1

Using a "free" scale in facet_wrap() allows for different axis scales between panels. In this case you want to free the x axis so you can use scales = "free_x".

I interpreted the other part of your question to be about lumping the bars of specific colors together in each panel. This depends on what info you want to use to lump them. You could define the factor order, for example. Here, I create a new variable that pastes the "A" value before the "ID" value and uses that on the x axis so the "C" group is plotted before the "U" group. I call this new variable "combo".

This gets the A colors lumped together, but also changes the axis tick labels:

df$combo = with(df, paste(A, ID))

ggplot(data = df, aes(x = combo, y = N, fill = A)) +
    geom_col(position="dodge") +
    facet_wrap(~B, scales = "free_x")

Setting different axis labels when using free scales in facets is tricky, but can be done if you provide both the labels and breaks as shown in this SO answer.

Using that approach your code could be:

ggplot(data = df, aes(x = combo, y = N, fill = A)) +
    geom_col(position="dodge") +
    facet_wrap(~B, scales = "free_x") +
    scale_x_discrete(labels = df$ID, breaks = df$combo)

Created on 2021-06-24 by the reprex package (v2.0.0)

aosmith
  • 34,856
  • 9
  • 84
  • 118
  • Thanks, @aosmith! I tried your code it worked in the example that I provide, but somehow the second solution for `labels` and `breaks` does not work in my real dataset. I checked the class of my original data except for N are all "character"s. When I used `scale_x_discrete(labels = df$ID, breaks = df$combo)`, the whole label for x-axis was just gone and the same color just did not lump together. Do you know what might cause this problem? (For the question, I simply just take the abbreviation of my original data for category A and B), and ID and N value are all the same. – XM_Z Jun 24 '21 at 19:30
  • A couple ideas on things to check for what could be going on @XM_Z: Does it work correctly without the `scale_x_discrete()` line? Is your real dataset named df? Did you successfully make the new "combo" variable in your real dataset? If your dataset is named df, print `df$combo` in your console. Could you include your real dataset or part of your real dataset in your question? For a small dataset this could involve pasting the output after running `dput(datasetname)` in your Console, where datasetname is the name of your real dataset. – aosmith Jun 24 '21 at 19:46
  • structure(list(ID = c("10", "11", "14", "15", "16", "18", "3", "5", "6", "8", "9", "n"), n = c(7L, 2L, 8L, 6L, 2L, 3L, 7L, 4L, 9L, 5L, 4L, 4L), trap = c("co2", "uv", "uv", "co2", "co2", "co2", "uv", "co2", "uv", "uv", "co2", "uv"), location = c("Plain", "Plain", "Canyon", "Plain", "Canyon", "Canyon", "Canyon", "Plain", "Canyon", "Plain", "Canyon", "Plain"), trapID = c("co2 10", "uv 11", "uv 14", "co2 15", "co2 16", "co2 18", "uv 3", "co2 5", "uv 6", "uv 8", "co2 9", "uv n")), row.names = c(NA, -12L), class = "data.frame") – XM_Z Jun 24 '21 at 20:00
  • Hi @aosmith, I just put my original dataset in the comments. I double-checked that I successfully created the "trapID" column which is your "combo" column. And the code works without adding `scale_x_discrete`. Also, the first solution you gave worked using `x=trapID`, but `scale_x_discrete` just didn't work. I double-checked the data. frame name and saw no issue with this part. – XM_Z Jun 24 '21 at 20:04
  • @XM_Z I reran things with your actual data, changing `A` to `trap` and things worked fine for me. You say you named your combo variable `trapID`. Did you switch to using that variable in `scale_x_discrete()`? I.e., `breaks = df$trapID` since `df$combo` doesn't exist. – aosmith Jun 24 '21 at 20:06
  • here is my code `ggplot(data=Jun,aes(x=ID,y=n,fill=trap)) + geom_col(position="dodge")+ facet_wrap(~location, scales="free_x") + scale_x_discrete(labels=Jun$ID,breaks=Jun$trapID)`. THe out come figure just did not have the tick mark on x-axis, and the colors were not lumped together... – XM_Z Jun 24 '21 at 20:13
  • 1
    I think you need `x = trapID` instead of `x = ID`. :) – aosmith Jun 24 '21 at 20:14
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/234177/discussion-between-xm-z-and-aosmith). – XM_Z Jun 24 '21 at 20:15