diff --git a/DESCRIPTION b/DESCRIPTION index fc8ac35..129cc7f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -25,7 +25,8 @@ Imports: purrr, Rcpp, rlang, - scales + scales, + scattermore Suggests: knitr, rmarkdown, diff --git a/NAMESPACE b/NAMESPACE index 1df63b4..ebaa1ba 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -45,6 +45,7 @@ importFrom(purrr,map_dbl) importFrom(purrr,partial) importFrom(rlang,list2) importFrom(scales,percent) +importFrom(scattermore,geom_scattermore) importFrom(stats,density) importFrom(stats,dunif) importFrom(stats,dweibull) diff --git a/R/accept_reject.r b/R/accept_reject.r index e59c033..c5c1ec1 100644 --- a/R/accept_reject.r +++ b/R/accept_reject.r @@ -92,7 +92,7 @@ #' f = dbinom, #' continuous = FALSE, #' args_f = list(size = 5, prob = 0.5), -#' xlim = c(0, 10) +#' xlim = c(0, 5) #' ) #' plot(x) #' diff --git a/R/plot.r b/R/plot.r index 2724d1b..58a5704 100644 --- a/R/plot.r +++ b/R/plot.r @@ -15,8 +15,8 @@ #' @param color_real_point Color of real probability points (discrete case) #' @param alpha Bar chart transparency (discrete case) and observed density #' (continuous case) -#' @param hist If TRUE, a histogram will be plotted in the continuous case, -#' comparing the theoretical density with the observed one. If FALSE, +#' @param hist If `TRUE`, a histogram will be plotted in the continuous case, +#' comparing the theoretical density with the observed one. If `FALSE`, #' [ggplot2::geom_density()] will be used instead of the histogram. #' #' @param ... Additional arguments. @@ -72,10 +72,10 @@ plot.accept_reject <- function( x, color_observed_density = "#BB9FC9", #"#E65A65", # "#FBBA78", - color_true_density = "#FE4F0E", + color_true_density = "#F890C2", #"#FE4F0E", color_bar = "#BB9FC9", #"#E65A65", #"#FCEFC3", color_observable_point = "#7BBDB3", - color_real_point = "#FE4F0E", + color_real_point = "#F890C2", #"#FE4F0E", alpha = .3, hist = TRUE, ... diff --git a/R/plot_inspect.r b/R/plot_inspect.r index 0d3fc60..854dbe8 100644 --- a/R/plot_inspect.r +++ b/R/plot_inspect.r @@ -103,7 +103,7 @@ inspect <- c = 1, alpha = 0.4, color_intersection = "#BB9FC9", - color_f = "#FE4F0E", + color_f = "#F890C2", #"#FE4F0E", color_f_base = "#7BBDB3" ) { diff --git a/R/qqplot.R b/R/qqplot.R index 99ca71a..b684f8e 100644 --- a/R/qqplot.R +++ b/R/qqplot.R @@ -22,17 +22,19 @@ quantile_custom_vec <- #' QQ-Plot #' QQ-Plot between observed quantiles and theoretical quantiles. -#' @param x Object of the class `accept_reject` returned by the function `accept_reject()`. +#' @param x Object of the class `accept_reject` returned by the function +#' `accept_reject()`. #' @param ... Additional arguments to be passed to methods. -#' @returns An object of classes `gg` and `ggplot` with the QQ-Plot of theoretical quantiles versus observed quantiles. +#' @returns An object of classes `gg` and `ggplot` with the QQ-Plot of +#' theoretical quantiles versus observed quantiles. #' @details #' Generic method to plot the QQ-Plot between observed quantiles and theoretical #' quantiles. The generic method will call the specific method #' `qqplot.accept_reject()`, which operates on objects of class accept_reject #' returned by the function `accept_reject()`. #' -#' @seealso [accept_reject()], [print.accept_reject()], [plot.accept_reject()] and -#' [inspect()]. +#' @seealso [accept_reject()], [print.accept_reject()], [plot.accept_reject()] +#' and [inspect()]. #' @export qqplot <- function(x, ...) { UseMethod("qqplot") @@ -41,12 +43,29 @@ qqplot <- function(x, ...) { #' QQ-Plot #' Plot the QQ-Plot between observed quantiles and theoretical quantiles. #' @param x Object of the class accept_reject returned by the function `accept_reject()`. -#' @param alpha Transparency of the points and reference line representing where the quantiles should be (theoretical quantiles). -#' @param color_points Color of the points (default is `"#FE4F0E"`). +#' @param alpha Transparency of the points and reference line representing where +#' the quantiles should be (theoretical quantiles). +#' @param color_points Color of the points (default is `"#F890C2"`). #' @param color_line Color of the reference line (detault is `"#BB9FC9"`). #' @param size_points Size of the points (default is `1`). #' @param size_line Thickness of the reference line (default is `1`). +#' @param parallel If `TRUE`, all cores will be used for internal calculations of +#' theoretical quantiles. The default is `FALSE`. Use TRUE if you find the plot +#' is taking too long. +#' @param cores Number of cores to be used if `parallel = TRUE`. Defalut is `NULL`, +#' which means all cores will be used. #' @param ... Additional arguments. +#' @details +#' Just like in the `accept_reject()` function, the `qqplot.accept_reject()` +#' function uses parallelism using FORK, meaning it works on Unix-based +#' operating systems (Linux and MacOS). What is parallelized are the internal +#' calculations of theoretical quantiles of the true distribution. This +#' parallelism will only be useful for excessively large samples. Additionally, +#' for samples larger than ten thousand, the `geom_scattermost()` function from +#' the [**scattermore**](https://CRAN.R-project.org/package=scattermore) library +#' is used to plot the points, as it is more efficient than `geom_point()` from +#' the [**ggplot2**](https://CRAN.R-project.org/package=ggplot2) library. +#' #' @return An object of classes gg and ggplot with the QQ-Plot between the #' observed quantiles generated by the return of the function `accept_reject()` #' and the theoretical quantiles of the true distribution. @@ -58,7 +77,7 @@ qqplot <- function(x, ...) { #' f = dbinom, #' continuous = FALSE, #' args_f = list(size = 5, prob = 0.5), -#' xlim = c(0, 10) +#' xlim = c(0, 5) #' ) #' qqplot(x) #' @@ -72,20 +91,59 @@ qqplot <- function(x, ...) { #' qqplot(y) #' @importFrom Rcpp evalCpp #' @importFrom ggplot2 ggplot geom_point geom_abline labs theme element_text -#' coord_cartesian scale_x_continuous scale_y_continuous -#' aes_string +#' coord_cartesian scale_x_continuous scale_y_continuous aes_string +#' @importFrom scattermore geom_scattermore +#' @importFrom parallel mclapply detectCores #' @export -qqplot.accept_reject <- function(x, alpha = 0.5, color_points = "#FE4F0E", color_line = "#BB9FC9", size_points = 1, size_line = 1, ...) { +qqplot.accept_reject <- + function(x, + alpha = 0.5, + color_points = "#F890C2", + color_line = "#BB9FC9", + size_points = 1, + size_line = 1, + parallel = FALSE, + cores = NULL, + ... + ) { + + continuous <- attr(x, "continuous") sample_quantiles <- sort(x) p <- (rank(sample_quantiles) - 0.375) / (length(sample_quantiles) + 0.25) - theoretical_quantiles <- quantile_custom_vec(x = x, p = p) + + theoretical_quantiles <- + unlist( + parallel::mclapply( + X = p, + FUN = function(i) quantile_custom_vec(x = x, i), + mc.cores = ifelse( + parallel, + ifelse(is.null(cores), parallel::detectCores(), cores), + 1L + ) + ) + ) + df <- data.frame(Theoretical = theoretical_quantiles, Sample = sample_quantiles) xlim <- attr(x, "xlim") - continuous <- attr(x, "continuous") plot <- ggplot(df, aes_string(x = "Theoretical", y = "Sample")) + - geom_abline(slope = 1, intercept = 0, color = color_line, size = size_line) + - geom_point(alpha = alpha, color = color_points, size = size_points) + + geom_abline(slope = 1, intercept = 0, color = color_line, size = size_line) + + if (continuous && length(x) >= 10e3){ + plot <- plot + + geom_scattermore( + pointsize = size_points + 2, + interpolate = TRUE, + color = color_points + ) + } else { + plot <- plot + + geom_point(alpha = alpha, color = color_points, size = size_points) + } + + plot <- + plot + coord_cartesian(xlim = xlim, ylim = xlim) + labs(x = "Theoretical Quantiles", y = "Sample Quantiles", title = "QQ-Plot") + theme( diff --git a/README.Rmd b/README.Rmd index 5caf938..b4d119b 100644 --- a/README.Rmd +++ b/README.Rmd @@ -96,10 +96,10 @@ p4 <- plot(d) plot_grid(p1, p2, p3, p4, nrow = 2L, labels = c("a", "b", "c", "d")) # QQ-Plots -q1 <- qqplot(a) -q2 <- qqplot(b) -q3 <- qqplot(c) -q4 <- qqplot(d) +q1 <- qqplot(a, size_points = 2) +q2 <- qqplot(b, size_points = 2) +q3 <- qqplot(c, size_points = 2) +q4 <- qqplot(d, size_points = 2) plot_grid(q1, q2, q3, q4, nrow = 2L, labels = c("a", "b", "c", "d")) ``` diff --git a/README.md b/README.md index 7dcb26a..3bb886c 100644 --- a/README.md +++ b/README.md @@ -190,10 +190,10 @@ plot_grid(p1, p2, p3, p4, nrow = 2L, labels = c("a", "b", "c", "d")) ``` r # QQ-Plots -q1 <- qqplot(a) -q2 <- qqplot(b) -q3 <- qqplot(c) -q4 <- qqplot(d) +q1 <- qqplot(a, size_points = 2) +q2 <- qqplot(b, size_points = 2) +q3 <- qqplot(c, size_points = 2) +q4 <- qqplot(d, size_points = 2) plot_grid(q1, q2, q3, q4, nrow = 2L, labels = c("a", "b", "c", "d")) ``` @@ -377,7 +377,7 @@ case_2 <- accept_reject( c = 1.2 ) toc() -#> 0.007 sec elapsed +#> 0.006 sec elapsed # Visualizing the results p1 <- plot(case_1) diff --git a/docs/articles/accept_reject.html b/docs/articles/accept_reject.html index eef05c8..570fce4 100644 --- a/docs/articles/accept_reject.html +++ b/docs/articles/accept_reject.html @@ -569,7 +569,7 @@
By default, the accept_reject function attempts to find the value of c that maximizes the probability of acceptance of the pseudo-random observations generated. However, it is possible to provide a value of c to the accept_reject()
function through the argument c
, where Y is a random variable for which we know how to generate observations. For the accept_reject()
function, it is not necessary to specify the probability function or probability density function of Y to generate observations of X for discrete and continuous cases, respectively. For the discrete and continuous cases, Y follows the discrete uniform distribution function and continuous uniform distribution function, respectively.
Since the probability of acceptance is 1/c, the accept_reject()
function attempts to find the minimum value of c that satisfies the description above. Unless you have compelling reasons to provide a value for the c
argument of the accept_reject()
function, it is recommended to use c = NULL
(default), allowing a value of c to be automatically determined.
The package is being versioned on GitHub. You can install the development version of AcceptReject, and to do this, you must first install the remotes package and then run the following command:
@@ -150,10 +150,10 @@Generating discrete observations
# QQ-Plots -q1 <- qqplot(a) -q2 <- qqplot(b) -q3 <- qqplot(c) -q4 <- qqplot(d) +q1 <- qqplot(a, size_points = 2) +q2 <- qqplot(b, size_points = 2) +q3 <- qqplot(c, size_points = 2) +q4 <- qqplot(d, size_points = 2) plot_grid(q1, q2, q3, q4, nrow = 2L, labels = c("a", "b", "c", "d"))
Color of the points (default is "#F890C2"
).
Just like in the accept_reject()
function, the qqplot.accept_reject()
+function uses parallelism using FORK, meaning it works on Unix-based
+operating systems (Linux and MacOS). What is parallelized are the internal
+calculations of theoretical quantiles of the true distribution. This
+parallelism will only be useful for excessively large samples. Additionally,
+for samples larger than ten thousand, the geom_scattermost()
function from
+the scattermore library
+is used to plot the points, as it is more efficient than geom_point()
from
+the ggplot2 library.
Object of the class accept_reject
returned by the function accept_reject()
.
Object of the class accept_reject
returned by the function
+accept_reject()
.
An object of classes gg
and ggplot
with the QQ-Plot of theoretical quantiles versus observed quantiles.
An object of classes gg
and ggplot
with the QQ-Plot of
+theoretical quantiles versus observed quantiles.