In R ggplot2, include stat_ecdf() endpoints (0,0) and (1,1)

后端 未结 1 2081
攒了一身酷
攒了一身酷 2021-02-09 20:05

I\'m trying to use stat_ecdf() to plot cumulative successes as a function of a rank score created by a predictive model.

#libraries
require(ggplot2)         


        
1条回答
  •  说谎
    说谎 (楼主)
    2021-02-09 20:30

    Unfortunately, the definition of stat_ecdf gives no wiggle room here; it determines the endpoints internally.

    There is a somewhat advanced solution. With the latest version of ggplot2 (devtools::install_github("hadley/ggplot2")), the extensibility is improved, to the point where it is possible to override this behavior, but not without some boilerplate.

    stat_ecdf2 <- function(mapping = NULL, data = NULL, geom = "step",
                          position = "identity", n = NULL, show.legend = NA,
                          inherit.aes = TRUE, minval=NULL, maxval=NULL,...) {
      layer(
        data = data,
        mapping = mapping,
        stat = StatEcdf2,
        geom = geom,
        position = position,
        show.legend = show.legend,
        inherit.aes = inherit.aes,
        stat_params = list(n = n, minval=minval,maxval=maxval),
        params = list(...)
      )
    }
    
    
    StatEcdf2 <- ggproto("StatEcdf2", StatEcdf,
      calculate = function(data, scales, n = NULL, minval=NULL, maxval=NULL, ...) {
        df <- StatEcdf$calculate(data, scales, n, ...)
        if (!is.null(minval)) { df$x[1] <- minval }
        if (!is.null(maxval)) { df$x[length(df$x)] <- maxval }
        df
      }
    )
    

    Now, stat_ecdf2 will behave the same as stat_ecdf, but with an optional minval and maxval parameter. So this will do the trick:

    ggplot(subset(df,target_outcome==1),aes(x = model_rank)) +
      stat_ecdf2(aes(colour = obs_set), size=1, minval=0, maxval=1) +
      scale_x_continuous(limits=c(0,1), labels=percent,breaks=seq(0,1,.1)) +
      xlab("Model Percentile") + ylab("Percent of Target Outcome") +
      scale_y_continuous(limits=c(0,1), labels=percent) +
      geom_segment(aes(x=0,y=0,xend=1,yend=1),
                   colour = "gray", linetype="longdash", size=1) +
      ggtitle("Gain Chart")
    

    The big caveat here is that I don't know if the current extensibility model will be supported in the future; it has changed several times in the past, and the change to use "ggproto" is recent -- like July 15th 2015 recent.

    As a plus, this gave me a chance to really dig into ggplot's internals, which is something that I've been meaning to do for a while.

    0 讨论(0)
提交回复
热议问题