daniel1noble / orchaRd

Extending the Orchard Plot for Meta-analysis
https://daniel1noble.github.io/orchaRd/
11 stars 6 forks source link

Cannot reorder levels of moderator (by=...) in bubble plot #61

Open RebekahMcKinnon opened 3 months ago

RebekahMcKinnon commented 3 months ago

I am trying to reorder the 'panel's created when fitting an interaction model. I have created several other plots to use in the publication using orchard_plot and the order on each is automatically 'reduced' on top and 'enlarged' below, but with the bubble_plot it's automatically the other way around and I can't seem to reorder them. I've tried setting levels to manually reorder but it doesn't work...

Model: final_model_BA <- rma.mv(yi = G_flip, V = vi, mods = ~ Treatment + Treatment:Breeding_years, random = list(~1 | RecNo, ~1 | EffectID), test = "t", method = "REML", sparse = TRUE, data = combined_data) final_model_BA

Plot code: I tried two different ways to reorder levels of the Treatment moderator with no success.

final_model_BA$Treatment <- factor(final_model_BA$Treatment, levels = c("reduced", "enlarged"))

final_model_BA$Treatment <- ordered(final_model_BA$Treatment, levels = c("reduced", "enlarged"))

figure4 <- orchaRd::bubble_plot(final_model_BA, group = "RecNo", by= "Treatment", mod = "Breeding_years", xlab = "Average Breeding Years", ylab = "Standardised Mean Difference", legend.pos="top.out", k.pos="top.right")+ scale_fill_manual(values=c("skyblue2", "tomato2")) + theme(legend.direction="horizontal", axis.title= element_text(size = 18), axis.text.y=element_text(size=12), axis.text.x=element_text(size=12), legend.text = element_text(size=12), legend.title=element_text(size=14), legend.text.align = 1) figure4

Figure created: image

but I would like to have reduced on top and enlarged on the bottom to match my other figures e.g., image

(by the way, for this figure I spent two hours trying to figure out how (1) to reorder the legend to show male on the left and female on the right because I thought that would make more sense given that the point for male is above that for female, and (2) colour the points for parental sex by sex, but also wasn't successful.)

Thanks for your help! Sorry if this is my incompetence rather than a bug.

RebekahMcKinnon commented 3 months ago

also, is it possible to change the text size for the words 'enlarged' and 'reduced' on that figure?

itchyshin commented 2 months ago

@RebekahMcKinnon - did you try to use factor and reorder before running the model? Also, see the vignette for an example of how to introduce different colors

daniel1noble commented 2 months ago

@RebekahMcKinnon Sorry I missed this. Yes, as @itchyshin says, setting the factor levels order for the moderator should fix the ordering question. Note that this needs to be done in the data before fitting the model, not after. Text size should be adjustable by modeming the theme() elements as normally done in ggplot

RebekahMcKinnon commented 2 months ago

Hi @itchyshin and @daniel1noble! Thank you both so much for your suggestions.

Here is my updated code:

combined_data$Treatment <- factor(combined_data$Treatment, levels = c("reduced", "enlarged"))

final_model_BA <- rma.mv(yi = G_flip, V = vi, mods = ~ Treatment + Treatment:Breeding_years, random = list(~1 | RecNo, ~1 | EffectID), test = "t", method = "REML", sparse = TRUE, data = combined_data) final_model_BA

figure4 <- orchaRd::bubble_plot(final_model_BA, group = "RecNo", by= "Treatment", mod = "Breeding_years", xlab = "Average Breeding Years", ylab = "Standardised Mean Difference (SMD)", legend.pos="top.out", k.pos="top.right")+ scale_fill_manual(values=c("tomato2", "skyblue2")) + theme(legend.direction="horizontal", axis.title= element_text(size = 18), axis.text.y=element_text(size=12), axis.text.x=element_text(size=12), legend.text = element_text(size=12), legend.title=element_text(size=14), legend.text.align = 1, strip.text = element_text(size = 18)) figure4


I was successfully able to change the size of the labels in the header of each panel using 'strip.text' however, I tried setting the factor levels order before running the model but the outcome was the same - the enlarged is still being plotted on top and reduced below, but weirdly this changed the order of the colours so that I no longer needed to set these manually to match my other figues:

image


For the second figure (i.e., the bottom figure in my first post, related to sex): [original] image

I was able to change the order of the parental sex in the legend by setting the factor levels before running the model, but it then also changed the shape of the points used to represent each sex so the problem remains the same in a sense:

code:

post_hoc4 <- metafor::rma.mv(yi = G_flip, V = vi, mods = ~ Treatment + Sex -1, # if add -1 means it shows separate intercepts random = list(~1 | RecNo, ~1 | EffectID), test = "t", method = "REML", sparse = TRUE, data = new_data) post_hoc4

orchaRd::orchard_plot(post_hoc4, group = "RecNo", mod = "Treatment", by = "Sex", xlab = "Standardised mean difference (SMD)", legend.pos= "top.right", condition.lab="Parental Sex", k.pos=c("left"), alpha=0.5, trunk.size=10, branch.size=2, fill=FALSE) + theme(legend.direction="horizontal", axis.title= element_text(size = 18), axis.text.y=element_text(size=18), axis.text.x=element_text(size=12), legend.text = element_text(size=12), legend.title=element_text(size=14), legend.text.align = 1) + scale_fill_manual(values=c("grey30", "grey30"))

outcome: image

it's interesting that reordering before running the model seemingly works for orchard_plot but not bubble_plot.

Also, regarding the setting of colours for the shapes representing sex I have tried many things. However, what I want to do is set the colour by sex i.e., male one colour, female a different colour, but it only seems to be possible to change the colours of both male and female grouped by treatment. For example:

by setting scale_fill_manual to two different colours: orchaRd::orchard_plot(post_hoc4, group = "RecNo", mod = "Treatment", by = "Sex", xlab = "Standardised mean difference (SMD)", legend.pos= "top.right", condition.lab="Parental Sex", k.pos=c("left"), alpha=0.5, trunk.size=10, branch.size=2, fill=FALSE) + theme(legend.direction="horizontal", axis.title= element_text(size = 18), axis.text.y=element_text(size=18), axis.text.x=element_text(size=12), legend.text = element_text(size=12), legend.title=element_text(size=14), legend.text.align = 1) + scale_fill_manual(values=c("green", "orange"))

I get a figure that looks like this: image

and setting colour = TRUE as suggested in the vignette (since I want to colour by the grouping variable) results in an error message:

code: orchaRd::orchard_plot(post_hoc4, group = "RecNo", mod = "Treatment", by = "Sex", xlab = "Standardised mean difference (SMD)", legend.pos= "top.right", condition.lab="Parental Sex", k.pos=c("left"), alpha=0.5, trunk.size=10, branch.size=2, fill=FALSE, colour=TRUE) + theme(legend.direction="horizontal", axis.title= element_text(size = 18), axis.text.y=element_text(size=18), axis.text.x=element_text(size=12), legend.text = element_text(size=12), legend.title=element_text(size=14), legend.text.align = 1)

error: Error in palette(): ! Insufficient values in manual scale. 26 needed but only 20 provided. Run rlang::last_trace() to see where the error occurred.

rlang::last_trace() <error/rlang_error> Error in palette(): ! Insufficient values in manual scale. 26 needed but only 20 provided.

Backtrace: ▆

  1. ├─base (local) <fn>(x)
  2. └─ggplot2:::print.ggplot(x)
  3. ├─ggplot2::ggplot_build(x)
  4. └─ggplot2:::ggplot_build.ggplot(x)
  5. └─base::lapply(data, npscales$map_df)
  6. └─ggplot2 (local) FUN(X[[i]], ...)
  7. └─ggplot2 (local) map_df(..., self = self)
  8. ├─base::unlist(...)
  9. └─base::lapply(self$scales, function(scale) scale$map_df(df = df))
  10. └─ggplot2 (local) FUN(X[[i]], ...)
  11. └─scale$map_df(df = df)
  12. └─ggplot2 (local) map_df(..., self = self)
  13. └─base::lapply(aesthetics, function(j) self$map(df[[j]]))
  14. └─ggplot2 (local) FUN(X[[i]], ...)
  15. └─self$map(df[[j]])
  16. └─ggplot2 (local) map(..., self = self)
  17. └─self$palette(n)
  18. └─ggplot2 (local) palette(...) Run rlang::last_trace(drop = FALSE) to see 2 hidden frames.

--

My apologies if I'm just missing something. I appreciate your help!

daniel1noble commented 2 months ago

@RebekahMcKinnon I think you need to set ordered = TRUE in

combined_data$Treatment <- factor(combined_data$Treatment, levels = c("reduced", "enlarged"), ordered = TRUE)

I can't be sure as I don't know what the str of the data looks like, but worth just checking in case this fixes the ordering. Basically, if you use str(data) it should clearly indicate that variable as being an 'Ord.factor`. If not, then the ordered = TRUE needs to be specified.

The colour = TRUE error. This could be due to the cb argument in orchard_plot also being set to TRUE, which only has 20 colours. If you set this to FALSE, does that fix the error? Either way, this points to a logical check that needs to be made so that error doesn't pop up. So thanks!

No need to apologise for anything! If something isn't clear we should fix it.

RebekahMcKinnon commented 2 months ago

@daniel1noble

I tried that: combined_data$Treatment <- factor(combined_data$Treatment, levels = c("reduced", "enlarged"), ordered=TRUE) str(combined_data$Treatment)

output of str(combined_data$Treatment):

str(combined_data$Treatment) Ord.factor w/ 2 levels "reduced"<"enlarged": 2 1 2 1 2 2 1 1 2 2 ...

so the ordering is working. And it also works based on my model output. However, the figure is still the same... image


about colours... I tried a few variations of the code including cb=FALSE but it didnt fix the problem.

E.g.,

(1) new_data$Sex <- factor(new_data$Sex, levels = c("male", "female"))

post_hoc4 <- metafor::rma.mv(yi = G_flip, V = vi, mods = ~ Treatment + Sex, random = list(~1 | RecNo, ~1 | EffectID), test = "t", method = "REML", sparse = TRUE, data = new_data) post_hoc4

orchaRd::orchard_plot(post_hoc4, group = "RecNo", mod = "Treatment", by = "Sex", xlab = "Standardised mean difference (SMD)", legend.pos= "top.right", condition.lab="Parental Sex", k.pos=c("left"), alpha=0.5, trunk.size=10, branch.size=2, colour=FALSE, cb=FALSE, fill=FALSE) + theme(legend.direction="horizontal", axis.title= element_text(size = 18), axis.text.y=element_text(size=18), axis.text.x=element_text(size=12), legend.text = element_text(size=12), legend.title=element_text(size=14), legend.text.align = 1) + scale_fill_manual(values=c("green", "orange"))

image

(2) without fill=FALSE image

(3) without fill=FALSE & without scale_fill_manual image

(4) with fill=FALSE but without scale_fill_manual image

BUT setting colour=TRUE with cb=FALSE i.e., orchaRd::orchard_plot(post_hoc4, group = "RecNo", mod = "Treatment", by = "Sex", xlab = "Standardised mean difference (SMD)", legend.pos= "top.right", condition.lab="Parental Sex", k.pos=c("left"), alpha=0.5, trunk.size=10, branch.size=2, colour=TRUE, cb=FALSE) + theme(legend.direction="horizontal", axis.title= element_text(size = 18), axis.text.y=element_text(size=18), axis.text.x=element_text(size=12), legend.text = element_text(size=12), legend.title=element_text(size=14), legend.text.align = 1)

still changes the colour of the Treatment related points rather than the Sex related shapes: image

adding fill=FALSE takes out the fill of the background colours: image

and having fill=FALSE but manually setting colours i.e., orchaRd::orchard_plot(post_hoc4, group = "RecNo", mod = "Treatment", by = "Sex", xlab = "Standardised mean difference (SMD)", legend.pos= "top.right", condition.lab="Parental Sex", k.pos=c("left"), alpha=0.5, trunk.size=10, branch.size=2, colour=TRUE, cb=FALSE, fill=FALSE) + theme(legend.direction="horizontal", axis.title= element_text(size = 18), axis.text.y=element_text(size=18), axis.text.x=element_text(size=12), legend.text = element_text(size=12), legend.title=element_text(size=14), legend.text.align = 1) + scale_fill_manual(values=c("green", "orange"))

seemingly doesnt change anything... image

RebekahMcKinnon commented 2 months ago

sorry one more, setting scale_color_manual instead of scale_fill_manual i.e., orchaRd::orchard_plot(post_hoc4, group = "RecNo", mod = "Treatment", by = "Sex", xlab = "Standardised mean difference (SMD)", legend.pos= "top.right", condition.lab="Parental Sex", k.pos=c("left"), alpha=0.5, trunk.size=10, branch.size=2, colour=FALSE, cb=FALSE, fill=FALSE) + theme(legend.direction="horizontal", axis.title= element_text(size = 18), axis.text.y=element_text(size=18), axis.text.x=element_text(size=12), legend.text = element_text(size=12), legend.title=element_text(size=14), legend.text.align = 1) + scale_color_manual(values=c("green", "orange"))

produces this:

image

daniel1noble commented 2 months ago

@RebekahMcKinnon Thanks for trying a few more things out. I think I figured out the issue with the facet_wrap ordering, but it turns out that there may be other issues with facet_wrap itself which is not an orchaRd function. Some code fixes I implemented in bubble_plot which should sort that out but are also not working. I tried to add a new argument cond_labels which provides users with options to set the label orders but that doesn't work with facet_wrap. So, we may just need to deal with the ordering issue. The changes made only seem to flip the colours around but not the actual panels. Sorry I can't so more for you on that front. I haven't had time to explore the colour stuff in detail. Sorry. Will try and get to that as soon as I can.