R/plotters.R

#' Plot balance and transactions by time.
#'
#' @param input A full path to file or directory, or a suitable dataset (see Details), to visualize.
#'
#' @importFrom dplyr "%>%"
#' @export

plot_statements <- function(input) {

    if ("data.frame" %in% class(input)) {
        data <- input
    } else if (stringr::str_detect(input, ".pdf")) {
        data <- rnordeatools::read_statement(input)
    } else {
        data <- rnordeatools::read_statements(input)
    }

    plot <- data %>%
      ggplot2::ggplot() +
        ggplot2::geom_point(ggplot2::aes(
            y = amount,
            x = record_date,
            color = type,
            label = counterparty
        )) +
        ggplot2::scale_x_date(date_breaks = "1 month") +
        ggplot2::theme_minimal()

    return(plotly::ggplotly(plot))
}

#' Plot counterparty totals as a table.
#'
#' For creating very simple, easily post-modifiable (svg) tables from small dataframes.
#'
#' @param input A data table (of class data.frame, tibble) to plot.
#' @param significant_digits How many digits to spare when rounding long numbers?
#' @param str_wrap_width How many characters to approximately print on one line?
#'
#' @return A ggplot2 object.
#'
#' @importFrom dplyr "%>%"
#' @export

plot_counterparties <- function(input,
                                significant_digits = 5,
                                str_wrap_width = 10,
                                alpha = 0.75) {

    if ("data.frame" %in% class(input)) {
        data <- input
    } else if (stringr::str_detect(input, ".pdf")) {
        data <- rnordeatools::read_statement(input)
    } else {
        data <- rnordeatools::read_statements(input)
    }

    data <- data %>%
        dplyr::filter(type == "transaction") %>%
        dplyr::group_by(counterparty) %>%
        dplyr::summarise(sum_amount = sum(amount)) %>%
        dplyr::arrange(sum_amount)

    # dont print massive tables
    stopifnot(nrow(data) < 200)

    # --- number formatter ----
    number_patterns <- rep("0", times = significant_digits) %>%
        purrr::accumulate(stringr::str_c) %>%
        stringr::str_c("\\.", ., "$") %>%
        purrr::prepend(str_sub(., start = 3)) %>%
        rev()
    number_replacement <- number_patterns %>%
        stringr::str_replace_all(c("0" = "  ", "\\." = "  ")) %>%
        stringr::str_remove_all("[^[:space:]]")
    replacement_map <- number_replacement %>%
        rlang::set_names(number_patterns)

    format_numbers <- . %>%
        signif(digits = significant_digits) %>%
        format(scientific = FALSE, trim = FALSE) %>%
        stringr::str_replace_all(" ", "  ") %>%
        stringr::str_replace_all(replacement_map)

    # --- text formatter -----
    format_text <- . %>%
        stringr::str_replace_all("[^[:alnum:]]+", " ") %>%
        stringr::str_wrap(str_wrap_width)

    # --- re-format input ---
    input_plotformat <- data %>%
        dplyr::mutate_if(is.character, format_text) %>%
        dplyr::mutate_if(is.numeric, format_numbers) %>%
        dplyr::mutate_all(dplyr::funs(dplyr::if_else(is.na(.), "", .))) %>%
        dplyr::mutate(
            row = dplyr::row_number(),
            even_row = dplyr::if_else(row %% 2 == 0, TRUE, FALSE)
        ) %>%
        tidyr::gather("variable", "value", -row, -even_row) %>%
        dplyr::mutate(tile_fill = dplyr::if_else(
            is.na(as.integer(value)),
            0,
            log(abs(as.integer(value))) * sign(as.integer(value))
        )) %>%
        dplyr::mutate(variable = dplyr::if_else(
            variable == "counterparty",
            "Counterparty",
            "Sum of transactions"
        ))

    # --- plot ---
    plot <- input_plotformat %>%
        ggplot2::ggplot() +
            ggplot2::geom_tile(
                ggplot2::aes(x = reorder(variable, row), y = row, fill = tile_fill),
                width = 0.97,
                alpha = alpha
            ) +
            ggplot2::geom_text(
                ggplot2::aes(x = reorder(variable, row), y = row, label = value),
                color = "#000000",
                lineheight = 0.8,
                size = 3
            ) +
            ggplot2::scale_x_discrete(position = "top")  +
            ggplot2::scale_fill_gradient2(
                low = "blue",
                high = "red",
                na.value = "white",
                guide = FALSE) +
            ggplot2::scale_y_continuous() +
            ggplot2::theme_void() +
            ggplot2::theme(axis.text.x = ggplot2::element_text(
                    margin = margin(t = 10, b = -15),
                    color = "#3c3c3c",
                    face = "bold"),
                  panel.background = ggplot2::element_rect(fill = "#ffffff", color = "#ffffff")
            )

    return(plot)
}
eteppo/r-nordea-analyysi documentation built on June 14, 2019, 3:48 a.m.