fsolt / dotwhisker

Dot-and-Whisker Plots of Regression Results
https://fsolt.org/dotwhisker/
Other
57 stars 10 forks source link

[Feature request] Ordering dw according to model list #98

Closed grszkthfr closed 2 years ago

grszkthfr commented 3 years ago

Hi,

thank you for this nice package.

I hope I don't miss the obvious, but it would be great to have finer control of the order of the plotted dotwhisker. In fact, I think it would be nice if the order of the dotwhisker match the order of the added/updated coefficients.

Current behavior: Coefficients are ordered from top to bottom for m1 - m2 - m3, but the dotwhiskers appear in reversed order m3 - m2 - m1.

Desired option: Coefficients are orderd from top to bottom for m1 - m2 - m3, and the dotwhisker appear in the same order m1 - m2 - m3.

So, what is the reasoning behind the given order? Isn't an order from old to new from top to bottom more intuitive?


According to a stackoverflow question and my (failed) own attempts, one requires an external package (broom) at the moment. On top, the hack fails if the models are not build onto each other (see m3c (where m1 is updated again) and the highlighted regions in the image).

Having an argument like reverse_dw defaulting to FALSE (or actually TURE as this reflects the current behavior?!) would be great.

Some reproducible code to illustrate the problem:

# adapted from SO (see above)
library(dotwhisker)
library(broom)
library(dplyr)

m1 <- lm(mpg ~ wt + cyl + disp + gear, data = mtcars)
m2 <- update(m1, . ~ . + hp)
m3 <- update(m2, . ~ . + am)

a <- bind_rows(
    tidy(m1) %>% mutate(model = "M1"),
    tidy(m2) %>% mutate(model = "M2"),
    tidy(m3) %>% mutate(model = "M3")
)
# default: from top to bottom: coef from m1-m3, but dws from m3-m1
dwa <- dwplot(a)

b <- a %>% arrange(desc(model))

b$model <- factor(b$model,
    levels = c("M1", "M2", "M3"),
    labels = c("M1", "M2", "M3")
)

# reversed: from top to bottom: coef from m1-m3, *and* dws from m1-m3
dwb <- dwplot(b) +
    scale_color_brewer(
        palette = "Set1",
        breaks = c("M1", "M2", "M3")
    )

m3c <- update(m1, . ~ . + am)

c <- rbind(
    tidy(m1) %>% mutate(model = "M1"),
    tidy(m2) %>% mutate(model = "M2"),
    tidy(m3c) %>% mutate(model = "M3")
) %>%
    arrange(desc(model))

# reversed failed: from top to bottom: coef from m1-m3-m2, *and* dws from m1-m3 (ignoring the guide which can be easily reverted)
dwc <- dwplot(c)

cowplot::plot_grid(dwa, dwb, dwc,
    labels = c("A", "B", "C"), label_size = 12,
    nrow = 1

image

Best Jonas