4

I'm trying to plot my data with ggplot2 but the data from my x-axis should be log transformed. I tried using the function coord_trans because I want to keep the original labels and just transform my coordinates but when I do this, all my points disappear from my graph. I have no idea why this is happening? Could it be because there are zero's in my data? And how can I fix this?

Here is my input for making the ggplot:

    library(afex)
    library(car)
    library(MASS)
    library(rockchalk)
    library(multcomp)
    library(lsmeans)
    library(gplots)
    library(ggplot2)
    library(tidyr)
    library(effects)
    library(scales)
    library(ggthemes)
    library(gtools)

    theme_set(theme_few(base_size=14)) 

    p=ggplot(data, aes(x=day, y=(propinfected), linetype=treatment, group=treatment)

   p + geom_smooth(aes(fill=treatment),colour="black", method="glm",
   family="quasibinomial")+ 
   coord_trans(xtrans = "log10")+
   geom_point(aes(fill=treatment),size=5,pch=21)+
   labs(x="Day", y="Above detection treshold", size=10)+
   scale_y_continuous(labels= percent,breaks=seq(0,1,by=0.2),limits=c(0,1))+ 
   scale_x_continuous(breaks=seq(0,16,by=4),limits=c(0,16))+
   scale_fill_manual(values=c("black","grey"))+
   theme(legend.justification=c(1,0), legend.position=c(1,0),
         legend.title=element_blank(),axis.text=element_text(size=20),
         axis.title=element_text(size=20),legend.text=element_text(size=15))

This is the model I work with:

fitlog=glm(propinfected~log10(day+1)*treatment,family=quasibinomial(link=logit), data=data)

This is the data I used:

dput(data)

structure(list(treatment = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 
1L, 2L, 1L, 2L), .Label = c("CTRL", "DWV"), class = "factor"), 
day = c(0L, 0L, 4L, 4L, 8L, 8L, 12L, 12L, 16L, 16L), infected = c(0L, 
20L, 11L, 20L, 15L, 18L, 16L, 19L, 19L, 19L), not_infected = c(20L, 
0L, 9L, 0L, 5L, 2L, 4L, 1L, 1L, 1L), propinfected = c(0, 
1, 0.55, 1, 0.75, 0.9, 0.8, 0.95, 0.95, 0.95)), .Names = c("treatment", 
"day", "infected", "not_infected", "propinfected"), row.names = c(NA, 
-10L), class = "data.frame")

When I plot my graph with the allEffects function, I get the correct plot, with correct lines and confidence bands. But I want to do it in ggplot because the allEffects plot is not so pretty.

plot(allEffects(fitlog),ylab="Above detection treshold",type="response")

Thanks for helping!

enter image description here

Aline
  • 51
  • 6
  • 3
    we don't have access to your dataset. Could you make it available using dput(). Just enough to reproduce the error! – MLavoie Jan 03 '16 at 00:02
  • I'm not sure what you mean with dput(). I'm very new in working with R. – Aline Jan 03 '16 at 00:15
  • 1
    in R run dput(nameofyourdataset) and copy the content in your post; a subset will do just enough to reproduce the error! – MLavoie Jan 03 '16 at 00:18
  • 1
    Or build a worked example using data in one of the many ggplot-oriented packages. – IRTFM Jan 03 '16 at 01:28
  • 1
    You can have a look at [this SO post](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) on how to make a great reproducible example in R. – Eric Fail Jan 03 '16 at 02:08
  • I used the dput() comment for my data and put it in my post. I hope this is what you meant. – Aline Jan 03 '16 at 09:51
  • I am not sure why but I get this Error: Unknown parameters: family..did you load a library not mentioned in your post? – MLavoie Jan 03 '16 at 11:13
  • I used a lot of packages and i'm not sure anymore wich one did the trick but I put all my used packages in my post now. Hope it works. – Aline Jan 03 '16 at 11:26

2 Answers2

1

If you define the formula in geom_smooth to be the formula of the model you fit with glm, you won't need coord_trans at all. In your case it would be y ~ log10(x + 1).

ggplot(data, aes(x=day, y=propinfected, linetype=treatment, group=treatment)) + 
    geom_smooth(aes(fill=treatment), formula = y ~ log10(x + 1), 
                colour="black", method="glm",
                method.args = list(family="quasibinomial")) +
    geom_point(aes(fill=treatment),size=5,pch=21) +
    labs(x="Day", y="Above detection treshold", size=10) +
    scale_y_continuous(labels= percent,breaks=seq(0,1,by=0.2),limits=c(0,1)) +
    scale_x_continuous(breaks=seq(0,16,by=4),limits=c(0,16)) +
    scale_fill_manual(values=c("black","grey")) +
    theme(legend.justification=c(1,0), legend.position=c(1,0),
          legend.title=element_blank(), axis.text=element_text(size=20),
          axis.title=element_text(size=20), legend.text=element_text(size=15))

enter image description here

To do it the way you were before, you actually need to use an appropriate scale_x function and then use coord_trans. It always takes me awhile to think through this, and this sentence from the coord_trans help page always helps me:

The difference between transforming the scales and transforming the coordinate system is that scale transformation occurs BEFORE statistics, and coordinate transformation afterwards.

So if you want to transform the x variable before fitting the model, you need to use scales for transforming. To show everything on the original scale, a coordinate transformation is what you need. So you'll end up using both to get the final product you want.

Here's a short example using scale_x_log10 and coord_trans:

ggplot(data, aes(x=day + 1, y=(propinfected), linetype=treatment, group=treatment)) + 
    geom_smooth(aes(fill=treatment), 
                colour="black", method="glm",
                method.args = list(family="quasibinomial")) +
    geom_point(aes(fill=treatment),size=5,pch=21) +
    labs(x="Day", y="Above detection treshold", size=10) +
    scale_y_continuous(labels= percent,breaks=seq(0,1,by=0.2),limits=c(0,1)) +
    scale_x_log10(labels = seq(0,16,by = 4), breaks=seq(1,17,by=4), limits=c(1,17)) +
    coord_trans(x = exp_trans(base = 10)) 
aosmith
  • 34,856
  • 9
  • 84
  • 118
  • 1
    Ooh thank you so much! This is exactly the graph I wanted. It makes sense now that I should define the formula in the ggplot. So silly of me that I did not think of this myself. Thanks again, you really made my day!! – Aline Jan 05 '16 at 16:21
0

Yes, it is because your data starts at day 0, and the log of 0 is undefined. You can solve this by adding one day to your date and then tweaking the labels so that they show the original date.

# Here we add 1 to the day:
    p <- ggplot(data, aes(x=day+1, y=(propinfected), linetype=treatment, group=treatment))

      # and here we use breaks 1 to 17, but labels 0 to 16. 
      p + geom_smooth(aes(fill=treatment),colour="black", method="glm",
                     family="quasibinomial")+ 
       coord_trans(xtrans = "log10")+
       geom_point(aes(fill=treatment),size=5,pch=21)+
       labs(x="Day", y="Above detection treshold", size=10)+
       scale_y_continuous(breaks=seq(0,1,by=0.2),limits=c(0,1))+ 
       scale_x_continuous(labels=seq(0,16,by=4),breaks=seq(1,17,by=4),limits=c(1,17))+
       scale_fill_manual(values=c("black","grey"))+
       theme(legend.justification=c(1,0), legend.position=c(1,0),
             legend.title=element_blank(),axis.text=element_text(size=20),
             axis.title=element_text(size=20),legend.text=element_text(size=15))

And your date is at log scale (Although I'm not sure why you would want this). enter image description here

RHA
  • 3,677
  • 4
  • 25
  • 48
  • I tried to do it with (x=day+1) and it works fine but when I use the coord_trans function all my points and lines just dissapear from my graph just like before. Could it be something with coord_trans? It is just really strange, I get no errors just an empty plot. And I'm transforming the data because my fitlog shows a better residuals fit then then the fit of my raw data. – Aline Jan 03 '16 at 21:24
  • When I use plott(allEffects), I get the correct plot and I want something similar but with ggplot where I can combine the 2 plots in 1 graph (I uploaded the image of the plot). – Aline Jan 03 '16 at 21:43
  • @Aline I don't think it's `coord_trans` because it worked for me. Is the picture in my answer what you are after? – RHA Jan 04 '16 at 06:56
  • Not exactly, I need to get somthing like with the plot(allEffects) but it should be in 1 graph and not 2 so I used ggplot because I thought that would be easier... Apparently I was wrong, I'm so confused now. – Aline Jan 04 '16 at 19:01
  • @Aline Aha, I think I understand what you want: you want the results from fitlog but then in one graph like the one above? – RHA Jan 04 '16 at 20:56
  • Yes exactly! And I want it to look something like I did in ggplot, with the same colors, lintypes and points. Because I don't like the graphs from the plot(allEffects). – Aline Jan 04 '16 at 22:22