Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

161 lines
4.3KB

  1. #' Animates a join operation
  2. #'
  3. #' Functions to visualise the join operations either static as a ggplot, or
  4. #' dynamic as a gif.
  5. #'
  6. #' @param x the x dataset
  7. #' @param y the y dataset
  8. #' @param by the by arguments for the join
  9. #' @param export the export type, either gif, first or last. The latter two
  10. #' export ggplots of the first/last state of the join
  11. #' @param ... further arguments passed to static_plot
  12. #'
  13. #' @return either a gif or a ggplot
  14. #'
  15. #' @seealso \code{\link[dplyr]{join}}
  16. #'
  17. #' @name animate_join
  18. #' @examples
  19. #' x <- data_frame(id = 1:3, x = paste0("x", 1:3))
  20. #' y <- data_frame(id = (1:4)[-3], y = paste0("y", (1:4)[-3]))
  21. #'
  22. #' # Animate the first or last state of the join
  23. #' animate_full_join(x, y, by = "id", export = "first")
  24. #' animate_full_join(x, y, by = "id", export = "last")
  25. #'
  26. #' # animate the transition as a gif (default)
  27. #' \donttest{
  28. #' animate_full_join(x, y, by = "id", export = "gif")
  29. #' }
  30. #'
  31. #' # different options include
  32. #' \donttest{
  33. #' animate_full_join(x, y, by = "id")
  34. #' animate_inner_join(x, y, by = "id")
  35. #' animate_left_join(x, y, by = "id")
  36. #' animate_right_join(x, y, by = "id")
  37. #' animate_semi_join(x, y, by = "id")
  38. #' animate_anti_join(x, y, by = "id")
  39. #'
  40. #' # further arguments can be passed to all animate_* functions
  41. #' animate_full_join(
  42. #' x, y, by = "id", export = "last",
  43. #' text_size = 5, title_size = 25,
  44. #' color_header = "black",
  45. #' color_other = "lightblue",
  46. #' color_fun = viridis::viridis
  47. #' )
  48. #' }
  49. #'
  50. #' # Save the results
  51. #' \donttest{
  52. #' # to save the ggplot, use
  53. #' fj <- animate_full_join(x, y, by = "id", export = "last")
  54. #' ggsave("full-join.pdf", fj)
  55. #'
  56. #' # to save the gif, use
  57. #' fj <- animate_full_join(x, y, by = "id", export = "gif")
  58. #' anim_save(fj, "full-join.gif")
  59. #' }
  60. animate_join <- function(
  61. x,
  62. y,
  63. by,
  64. type = c("full_join", "inner_join", "left_join", "right_join",
  65. "semi_join", "anti_join"),
  66. export = c("gif", "first", "last"),
  67. ...
  68. ) {
  69. type <- match.arg(type)
  70. export <- match.arg(export)
  71. if (rlang::is_quosure(x)) {
  72. x_name <- rlang::quo_name(x)
  73. x <- rlang::eval_tidy(x)
  74. } else {
  75. x_name <- rlang::quo_name(rlang::enquo(x))
  76. }
  77. if (rlang::is_quosure(y)) {
  78. y_name <- rlang::quo_name(y)
  79. y <- rlang::eval_tidy(y)
  80. } else {
  81. y_name <- rlang::quo_name(rlang::enquo(y))
  82. }
  83. by_args <- if (length(by) == 1) sprintf("\"%s\"", by) else
  84. sprintf("c(\"%s\")", paste(by, collapse = "\", \""))
  85. title <- sprintf(paste0(type, "(%s, %s, by = %s)"), x_name, y_name, by_args)
  86. if (type %in% c("semi_join", "anti_join")) {
  87. # for semi and anti_joins, there is no adding of multiple rows
  88. y <- dplyr::distinct(y)
  89. }
  90. ll <- process_join(x, y, by, ...)
  91. step0 <- bind_rows(ll$x, ll$y) %>% mutate(.frame = 0, .alpha = 1)
  92. step1 <- move_together(ll$x, ll$y, type) %>% mutate(.frame = 1)
  93. all <- bind_rows(step0, step1)
  94. if (export == "gif") {
  95. animate_plot(all, title, ...)
  96. } else if (export == "first") {
  97. title <- ""
  98. static_plot(step0, title, ...)
  99. } else if (export == "last") {
  100. static_plot(step1, title, ...)
  101. }
  102. }
  103. #' @rdname animate_join
  104. #' @export
  105. animate_full_join <- function(x, y, by, export = "gif", ...) {
  106. x <- rlang::enquo(x)
  107. y <- rlang::enquo(y)
  108. animate_join(x, y, by, type = "full_join", export = export, ...)
  109. }
  110. #' @rdname animate_join
  111. #' @export
  112. animate_inner_join <- function(x, y, by, export = "gif", ...) {
  113. x <- rlang::enquo(x)
  114. y <- rlang::enquo(y)
  115. animate_join(x, y, by, type = "inner_join", export = export, ...)
  116. }
  117. #' @rdname animate_join
  118. #' @export
  119. animate_left_join <- function(x, y, by, export = "gif", ...) {
  120. x <- rlang::enquo(x)
  121. y <- rlang::enquo(y)
  122. animate_join(x, y, by, type = "left_join", export = export, ...)
  123. }
  124. #' @rdname animate_join
  125. #' @export
  126. animate_right_join <- function(x, y, by, export = "gif", ...) {
  127. x <- rlang::enquo(x)
  128. y <- rlang::enquo(y)
  129. animate_join(x, y, by, type = "right_join", export = export, ...)
  130. }
  131. #' @rdname animate_join
  132. #' @export
  133. animate_semi_join <- function(x, y, by, export = "gif", ...) {
  134. x <- rlang::enquo(x)
  135. y <- rlang::enquo(y)
  136. animate_join(x, y, by, type = "semi_join", export = export, ...)
  137. }
  138. #' @rdname animate_join
  139. #' @export
  140. animate_anti_join <- function(x, y, by, export = "gif", ...) {
  141. x <- rlang::enquo(x)
  142. y <- rlang::enquo(y)
  143. animate_join(x, y, by, type = "anti_join", export = export, ...)
  144. }