A 'ggplot2' Extension for Visualizing Density, Distribution, Hazard, or Survival Functions using the 'logspline' Package
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.1 KiB

1 year ago
  1. #' Base ggproto classes for gglogspline
  2. #'
  3. #' @section Computed variables:
  4. #'
  5. #' - `density` : the density estimate
  6. #' - `count`: computed counts (similar to [ggplots::stat_density()])
  7. #' - `probs`: distribution function
  8. #' - `survival`: survival function
  9. #' - `hazard` : hazard function
  10. #'
  11. #' By default the `y` aesthetic is mapped to `stat(density)`
  12. #'
  13. #' @rdname gglogspline-ggproto
  14. #' @export
  15. StatLogspline <- ggproto(
  16. "StatLogspline", Stat,
  17. compute_group = function(data, scales,
  18. n = 100, max_knots = 0, n_knots = 0,
  19. min_d = -1, error_action = 2) {
  20. logspline(
  21. data$x,
  22. maxknots = max_knots,
  23. nknots = n_knots,
  24. mind = min_d,
  25. error.action = error_action
  26. ) -> lsp
  27. # computed upper and lower bounds for simplicity
  28. u1 <- qlogspline(0.01, lsp)
  29. u2 <- qlogspline(0.99, lsp)
  30. # we need these to compute the new x-axis values
  31. u3 <- 1.1 * u1 - 0.1 * u2
  32. u4 <- 1.1 * u2 - 0.1 * u1
  33. # compute the new X-axis values and the log-density
  34. xx <- (0:(n - 1))/(n - 1) * (u4 - u3) + u3
  35. den <- dlogspline(xx, lsp)
  36. prb <- plogspline(xx, lsp)
  37. # our new data frame with an extra computed stat for the count
  38. data.frame(
  39. x = xx,
  40. density = den,
  41. probs = prb,
  42. survival = 1 - prb,
  43. hazard = den / (1 - prb),
  44. count = den * nrow(data),
  45. stringsAsFactors = FALSE
  46. )
  47. },
  48. required_aes = c("x"), # we only accept one parameter
  49. default_aes = aes(
  50. y = stat(density) # by default we use the computed stat
  51. )
  52. )
  53. #' Computes and draws...
  54. #'
  55. #' @inheritParams ggplot2::stat_density
  56. #' @param n numbe of points for the density estimation (larger == smoother)
  57. #' @param max_knots the maximum number of knots. The routine stops adding knots when
  58. #' this number of knots is reached. The method has an automatic rule for selecting
  59. #' maxknots if this parameter is not specified.
  60. #' @param n_knots forces the method to start with nknots knots. The method has an automatic
  61. #' rule for selecting nknots if this parameter is not specified.
  62. #' @param min_d minimum distance, in order statistics, between knots.
  63. #' @param error_action see `error.action` in [logspline::plot.logspline()]
  64. #' @export
  65. #' @examples
  66. #' library(ggplot2)
  67. #'
  68. #' set.seed(1)
  69. #' data.frame(
  70. #' val = rnorm(100)
  71. #' ) -> xdf
  72. #'
  73. #' ggplot(xdf) + stat_logspline(aes(val))
  74. stat_logspline <- function(mapping = NULL, data = NULL, geom = "area",
  75. position = "identity", na.rm = FALSE, show.legend = NA,
  76. inherit.aes = TRUE,
  77. # our custom params
  78. n = 100, max_knots = 0, n_knots = 0, min_d = -1, error_action = 2,
  79. ...) {
  80. layer(
  81. stat = StatLogspline,
  82. data = data,
  83. mapping = mapping,
  84. geom = geom,
  85. position = position,
  86. show.legend = show.legend,
  87. inherit.aes = inherit.aes,
  88. params = list(
  89. na.rm = na.rm,
  90. # pass on our fancy custom params
  91. n = n,
  92. max_knots = max_knots,
  93. n_knots = n_knots,
  94. error_action = error_action,
  95. ...
  96. )
  97. )
  98. }