diff --git a/NAMESPACE b/NAMESPACE index 42285ba..52b0022 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,6 @@ # Generated by roxygen2: do not edit by hand export(geometric_brownian_motion) +export(random_normal_drift_walk) export(random_normal_walk) export(rw30) diff --git a/NEWS.md b/NEWS.md index 2c7c397..41e5253 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,7 @@ None ## New Features 1. Fix #9 - Add Function `rw30()` to generate 30 random walks of 100 steps each. 2. Fix #17 - Add Function `geometric_brownian_motion()` +3. Fix #18 - Add Function `random_normal_drift_walk()` ## Minor Improvements and Fixes None diff --git a/R/auto-rw30.R b/R/auto-rw30.R index 1d111a3..937298a 100644 --- a/R/auto-rw30.R +++ b/R/auto-rw30.R @@ -48,7 +48,6 @@ rw30 <- function() { walks_tibble <- dplyr::tibble( x = 1:num_steps, !!!stats::setNames(walks, 1:num_walks) - #!!!stats::setNames(walks, paste0("walk_", 1:num_walks)) ) # Pivot the tibble longer diff --git a/R/gen-random-drift-walk.R b/R/gen-random-drift-walk.R new file mode 100644 index 0000000..9e99bba --- /dev/null +++ b/R/gen-random-drift-walk.R @@ -0,0 +1,95 @@ +#' Generate Multiple Random Walks with Drift +#' +#' @family Generator Functions +#' +#' @author Steven P. Sanderson II, MPH +#' +#' @details +#' This function generates multiple random walks with a specified drift. +#' Each walk is generated using a normal distribution for the steps, with an +#' additional drift term added to each step. +#' +#' @description +#' This function generates a specified number of random walks, each consisting +#' of a specified number of steps. The steps are generated from a normal +#' distribution with a given mean and standard deviation. An additional drift +#' term is added to each step to introduce a consistent directional component +#' to the walks. +#' +#' @param .num_walks Integer. The number of random walks to generate. Default is 25. +#' @param .n Integer. The number of steps in each random walk. Default is 100. +#' @param .mu Numeric. The mean of the normal distribution used for generating steps. Default is 0. +#' @param .sd Numeric. The standard deviation of the normal distribution used for generating steps. Default is 1. +#' @param .drift Numeric. The drift term to be added to each step. Default is 0.1. +#' +#' @examples +#' library(ggplot2) +#' +#' walks <- random_normal_drift_walk(.num_walks = 10, .n = 50, .mu = 0, .sd = 1, +#' .drift = 0.05) +#' ggplot(walks, ggplot2::aes(x = x, y = y, group = walk_number, color = walk_number)) + +#' geom_line() + +#' labs(title = "Random Walks with Drift", x = "Time", y = "Value") + +#' theme_minimal() + +#' theme(legend.position = "none") +#' +#' @return A tibble in long format with columns `walk_number`, `x` (step index), +#' and `y` (walk value). The tibble has attributes for the number of walks, +#' number of steps, mean, standard deviation, and drift. +#' +#' @name random_normal_drift_walk +NULL +#' @rdname random_normal_drift_walk +#' @export + +random_normal_drift_walk <- function(.num_walks = 25, .n = 100, .mu = 0, + .sd = 1, .drift = 0.1) { + + num_walks <- as.integer(.num_walks) + num_steps <- as.integer(.n) + mu <- as.numeric(.mu) + sd <- as.numeric(.sd) + drift <- as.numeric(.drift) + #dr <- seq(from = drift, to = n, length.out = n) + + # Function to generate a single random walk + single_random_walk_with_drift <- function(num_steps, mu, sd, drift) { + wn <- stats::rnorm(n = num_steps, mean = mu, sd = sd) + rw <- cumsum(stats::rnorm(n = num_steps, mean = mu, sd = sd)) + res <- wn + rw + drift + return(res) + } + + # Generate the walks + walks <- replicate( + num_walks, + single_random_walk_with_drift(num_steps, mu, sd, drift), + simplify = FALSE + ) + + # Create a tibble with the walks + walks_tibble <- dplyr::tibble( + x = 1:num_steps, + !!!stats::setNames(walks, 1:num_walks) + ) + + # Pivot the tibble longer + walks_long <- tidyr::pivot_longer( + walks_tibble, + cols = -x, + names_to = "walk_number", + values_to = "y" + ) |> + dplyr::mutate(walk_number = factor(walk_number)) |> + dplyr::select(walk_number, x, y) |> + dplyr::arrange(walk_number, x) + + attr(walks_long, "num_walks") <- num_walks + attr(walks_long, "num_steps") <- num_steps + attr(walks_long, "mu") <- mu + attr(walks_long, "sd") <- sd + attr(walks_long, "drift") <- drift + attr(walks_long, "fns") <- "random_normal_drift_walk" + + return(walks_long) +} diff --git a/docs/articles/getting-started.html b/docs/articles/getting-started.html index d047505..31dcd75 100644 --- a/docs/articles/getting-started.html +++ b/docs/articles/getting-started.html @@ -62,7 +62,16 @@
library(RandomWalker)
+#>
+#> == Welcome to RandomWalker ========================================================
+#> If you find this package useful, please leave a star:
+#> https://github.com/spsanderson/RandomWalker
+#>
+#> If you encounter a bug or want to request an enhancement please file an issue at:
+#> https://github.com/spsanderson/RandomWalker/issues
+#>
+#> Thank you for using RandomWalker
So how do you use this anyways?
diff --git a/docs/index.html b/docs/index.html index b3d0612..88ead1a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -11,8 +11,8 @@ - - + + Skip to contents @@ -69,21 +69,17 @@
library(RandomWalker)
## basic example code
-rw30()
-#> # A tibble: 3,000 × 3
-#> walk x value
-#> <fct> <int> <dbl>
-#> 1 walk_1 1 0
-#> 2 walk_1 2 0.916
-#> 3 walk_1 3 1.26
-#> 4 walk_1 4 1.84
-#> 5 walk_1 5 2.53
-#> 6 walk_1 6 1.39
-#> 7 walk_1 7 1.94
-#> 8 walk_1 8 2.42
-#> 9 walk_1 9 1.86
-#> 10 walk_1 10 2.27
-#> # ℹ 2,990 more rows