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.

93 lines
3.0KB

  1. #' Transform any function into a valid stat function for the table
  2. #'
  3. #' Transform a function into a valid stat function for the table
  4. #'
  5. #' NA values are removed from the data
  6. #'
  7. #' Applying the function on a numerical vector should return one value
  8. #'
  9. #' Applying the function on a factor should return nlevels + 1 value, or one value per factor level
  10. #'
  11. #' See \code{parse_formula} for the usage for formulaes.
  12. #' @param f The function to try to apply, or a formula combining two functions
  13. #' @param x A vector
  14. #' @export
  15. #' @return The results for the function applied on the vector, compatible with the format of the result table
  16. #' @keywords internal
  17. statify <- function(x, f) {
  18. # Discard NA values
  19. x <- stats::na.omit(x)
  20. ## Deprecate conditional formula
  21. if (length(f) == 3) # remove after 1.0
  22. f <- parse_formula(x, f)
  23. else
  24. f <- rlang::as_function(f)
  25. # Try f(x), silent warnings and fail with NA
  26. res <- tryCatch(f(x),
  27. warning = function(e) suppressWarnings(f(x)),
  28. error = function(e) NA)
  29. # If x is a factor and f(x) behaves as expected (nlevel + total value), return f(x), or apply f(x) on each level, or fail with n+1 NA
  30. if (is.factor(x)) {
  31. if (length(res) == nlevels(x) + 1) res
  32. else if (length(res) == 1) {
  33. c(res, lapply(levels(x), function(lvl) {
  34. tryCatch(f(x[x == lvl]),
  35. warning = function(e) suppressWarnings(f(x[x == lvl])),
  36. error = function(e) NA)
  37. }) %>% unlist)
  38. }
  39. else rep(NA, nlevels(x) + 1)
  40. # If it is a numeric, return f(x) if it behaves as expected (ONE value), or fail with NA
  41. } else {
  42. if (length(res) == 1) {
  43. if (is.numeric(res) | is.na(res)) res
  44. else as.character(res)
  45. }
  46. else NA
  47. }
  48. }
  49. #' Function to create a list of statistics to use in desctable
  50. #'
  51. #' This function takes a dataframe as argument and returns a list of statistcs in the form accepted by desctable.
  52. #'
  53. #' You can define your own automatic function, as long as it takes a dataframe as argument and returns a list of functions, or formulas defining conditions to use a stat function.
  54. #'
  55. #' @param data The dataframe to apply the statistic to
  56. #' @return A list of statistics to use, assessed from the content of the dataframe
  57. #' @export
  58. stats_auto <- function(data) {
  59. data %>%
  60. lapply(is.numeric) %>%
  61. unlist() %>%
  62. any -> numeric
  63. data %>%
  64. lapply(is.factor) %>%
  65. unlist() %>%
  66. any() -> fact
  67. stats <- list("Min" = min,
  68. "Q1" = ~quantile(., .25),
  69. "Med" = stats::median,
  70. "Mean" = mean,
  71. "Q3" = ~quantile(., .75),
  72. "Max" = max,
  73. "sd" = stats::sd,
  74. "IQR" = IQR)
  75. if (fact & numeric)
  76. c(list("N" = length,
  77. "%" = percent),
  78. stats)
  79. else if (fact & !numeric)
  80. list("N" = length,
  81. "%" = percent)
  82. else if (!fact & numeric)
  83. stats
  84. }