Search code examples
rplotggplot2coefplot

Change colors of select lines in ggplot2 coefficient plot in R


I would like to change the color of coefficient lines based on whether the point estimate is negative or positive in a ggplot2 coefficient plot in R. For example:

require(coefplot)
set.seed(123)
dat <- data.frame(x = rnorm(100), z = rnorm(100))
mod1 <- lm(y1 ~ x + z, data = dat)
coefplot.lm(mod1)   

Which produces the following plot:

enter image description here

In this plot, I would like to change the "x" variable to red when plotted. Any ideas? Thanks.


Solution

  • I think, you cannot do this with a plot produced by coefplot.lm. The package coefplot uses ggplot2 as the plotting system, which is good itself, but does not allow to play with colors as easily as you would like. To achieve the desired colors, you need to have a variable in your dataset that would color-code the values; you need to specify color = color-code in aes() function within the layer that draws the dots with CE. Apparently, this is impossible to do with the output of coefplot.lm function. Maybe, you can change the colors using ggplot2 ggplot_build() function. I would say, it's easier to write your own function for this task.


    I've done this once to plot odds. If you want, you may use my code. Feel free to change it. The idea is the same as in coefplot. First, we extract coefficients from a model object and prepare the data set for plotting; second, actually plot.


    The code for extracting coefficients and data set preparation

    df_plot_odds <- function(x){
    tmp<-data.frame(cbind(exp(coef(x)), exp(confint.default(x))))
    odds<-tmp[-1,]
    names(odds)<-c('OR', 'lower', 'upper')
    odds$vars<-row.names(odds)
    odds$col<-odds$OR>1
    odds$col[odds$col==TRUE] <-'blue'
    odds$col[odds$col==FALSE] <-'red'
    odds$pvalue <- summary(x)$coef[-1, "Pr(>|t|)"]
    return(odds)
    }
    

    Plot the output of the extract function

    plot_odds <- function(df_plot_odds, xlab="Odds Ratio", ylab="", asp=1){
        require(ggplot2)
        p <- ggplot(df_plot_odds, aes(x=vars, y=OR, ymin=lower, ymax=upper),asp=asp) + 
            geom_errorbar(aes(color=col),width=0.1) + 
            geom_point(aes(color=col),size=3)+
            geom_hline(yintercept = 1, linetype=2) +
            scale_color_manual('Effect', labels=c('Positive','Negative'),
                              values=c('blue','red'))+   
            coord_flip() +
            theme_bw() +
            theme(legend.position="none",aspect.ratio = asp)+
            ylab(xlab) +
            xlab(ylab) #switch because of the coord_flip() above
        return(p)
    }
    

    Plotting your example

    set.seed(123)
    dat <- data.frame(x = rnorm(100),y = rnorm(100), z = rnorm(100))
    mod1 <- lm(y ~ x + z, data = dat)
    df <- df_plot_odds(mod1)
    plot <- plot_odds(df)
    plot
    

    Which yields

    enter image description here

    Note that I chose theme_wb() as the default. Output is a ggplot2object. So, you may change it quite a lot.