Skip to content

Commit 38760b6

Browse files
committed
option to return parameters from growthSim
1 parent 8b8a539 commit 38760b6

2 files changed

Lines changed: 111 additions & 27 deletions

File tree

R/growthSim.R

Lines changed: 106 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#' Changepoints should be specified as "changePointX" or "fixedChangePointX" as in
2424
#' \code{\link{growthSS}}.
2525
#' @param D If decay is being simulated then this is the starting point for decay. This defaults to 0.
26+
#' @param returnParams Logical, should exact parameter values making each line be returned as part of
27+
#' the data? This may be useful for model evaluation on test data. Defaults to FALSE.
2628
#'
2729
#' @return Returns a dataframe of example growth data following the input parameters.
2830
#'
@@ -271,7 +273,8 @@ growthSim <- function(
271273
"monomolecular", "exponential", "linear", "power law", "frechet", "weibull", "gumbel",
272274
"logarithmic", "bragg", "lorentz", "beta"
273275
),
274-
n = 20, t = 25, params = list(), D = 0) {
276+
n = 20, t = 25, params = list(), D = 0,
277+
returnParams = FALSE) {
275278
if (grepl("count:", model)) {
276279
COUNT <- TRUE
277280
model <- trimws(gsub("count:", "", model))
@@ -316,9 +319,9 @@ growthSim <- function(
316319
}
317320
#* decide which internal funciton to use
318321
if (!grepl("\\+", model)) {
319-
out <- .singleGrowthSim(model, n, t, params, noise, D, int)
322+
out <- .singleGrowthSim(model, n, t, params, noise, D, int, returnParams)
320323
} else {
321-
out <- .multiGrowthSim(model, n, t, params, noise, D, int)
324+
out <- .multiGrowthSim(model, n, t, params, noise, D, int, returnParams)
322325
}
323326
if (COUNT) {
324327
out <- do.call(rbind, lapply(split(out, interaction(out$group, out$id)), function(sub) {
@@ -334,7 +337,8 @@ growthSim <- function(
334337
#' @keywords internal
335338
#' @noRd
336339

337-
.multiGrowthSim <- function(model, n = 20, t = 25, params = list(), noise = NULL, D = 0, int) {
340+
.multiGrowthSim <- function(model, n = 20, t = 25, params = list(), noise = NULL, D = 0, int,
341+
returnParams = FALSE) {
338342
component_models <- trimws(strsplit(model, "\\+")[[1]])
339343

340344
firstModel <- component_models[1]
@@ -439,7 +443,8 @@ growthSim <- function(
439443
#' @keywords internal
440444
#' @noRd
441445

442-
.singleGrowthSim <- function(model, n = 20, t = 25, params = list(), noise = NULL, D, int) {
446+
.singleGrowthSim <- function(model, n = 20, t = 25, params = list(), noise = NULL, D, int,
447+
returnParams = FALSE) {
443448
models <- .available_models()
444449

445450
if (grepl("decay", model)) {
@@ -450,7 +455,7 @@ growthSim <- function(
450455
}
451456

452457
matched_model <- match.arg(model, models)
453-
gsi <- match.fun(paste0("gsi_", gsub(" ", "", matched_model)))
458+
gsi <- match.fun(paste0(".gsi_", gsub(" ", "", matched_model)))
454459

455460
if (decay) {
456461
gsid <- function(D = 0, ...) {
@@ -465,18 +470,25 @@ growthSim <- function(
465470
out <- do.call(rbind, lapply(seq_along(params[[1]]), function(i) {
466471
pars <- lapply(params, function(p) p[i])
467472
e_df <- as.data.frame(rbind(do.call(rbind, lapply(1:n, function(e) {
473+
gs_res <- gsid(D = D, 1:t, pars, noise)
468474
iter_data <- data.frame(
469475
"id" = paste0("id_", e), "group" = letters[i], "time" = 1:t,
470-
"y" = gsid(D = D, 1:t, pars, noise), stringsAsFactors = FALSE
476+
"y" = gs_res$y, stringsAsFactors = FALSE
471477
)
478+
if (returnParams) {
479+
iter_data <- cbind(iter_data, gs_res$pars[rep(1, nrow(iter_data)), ])
480+
}
472481
if (int) {
473-
iter_data$y <- iter_data$y + rnorm(1, mean = pars[["I"]], sd = noise[["I"]])
482+
I_iter <- rnorm(1, mean = pars[["I"]], sd = noise[["I"]])
483+
iter_data$y <- iter_data$y + I_iter
484+
if (returnParams) {
485+
iter_data$I <- I_iter
486+
}
474487
}
475488
return(iter_data)
476489
}))))
477490
return(e_df)
478491
}))
479-
480492
return(out)
481493
}
482494

@@ -485,115 +497,183 @@ growthSim <- function(
485497
#* ***** `gsi functions to simulate individual plants` *****
486498
#* ************************************************************
487499

500+
#' @keywords internal
501+
#' @noRd
488502
gsi_logistic <- function(x, pars, noise) {
489503
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
490504
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
491505
c_r <- pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])
492-
return(a_r / (1 + exp((b_r - x) / c_r)))
506+
y <- a_r / (1 + exp((b_r - x) / c_r))
507+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r)))
493508
}
509+
510+
#' @keywords internal
511+
#' @noRd
494512
gsi_logistic4 <- function(x, pars, noise) {
495513
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
496514
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
497515
c_r <- pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])
498516
d_r <- pars[["D"]] + rnorm(1, mean = 0, sd = noise[["D"]])
499-
return(d_r + (a_r - d_r) / (1 + exp((b_r - x) / c_r)))
517+
y <- d_r + (a_r - d_r) / (1 + exp((b_r - x) / c_r))
518+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r, "D" = d_r)))
500519
}
520+
521+
#' @keywords internal
522+
#' @noRd
501523
gsi_logistic5 <- function(x, pars, noise) {
502524
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
503525
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
504526
c_r <- pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])
505527
d_r <- pars[["D"]] + rnorm(1, mean = 0, sd = noise[["D"]])
506528
e_r <- pars[["E"]] + rnorm(1, mean = 0, sd = noise[["E"]])
507-
return(d_r + ((a_r - d_r) / (1 + exp((b_r - x) / c_r)) ^ e_r))
529+
y <- d_r + ((a_r - d_r) / (1 + exp((b_r - x) / c_r)) ^ e_r)
530+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r, "D" = d_r, "E" = e_r)))
508531
}
532+
533+
#' @keywords internal
534+
#' @noRd
509535
gsi_gompertz <- function(x, pars, noise) {
510536
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
511537
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
512538
c_r <- pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])
513-
return(a_r * exp(-b_r * exp(-c_r * x)))
539+
y <- a_r * exp(-b_r * exp(-c_r * x))
540+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r)))
514541
}
542+
543+
#' @keywords internal
544+
#' @noRd
515545
gsi_doublelogistic <- function(x, pars, noise) {
516546
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
517547
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
518548
c_r <- pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])
519549
a2_r <- pars[["A2"]] + rnorm(1, mean = 0, sd = noise[["A2"]])
520550
b2_r <- pars[["B2"]] + rnorm(1, mean = 0, sd = noise[["B2"]])
521551
c2_r <- pars[["C2"]] + rnorm(1, mean = 0, sd = noise[["C2"]])
522-
return(a_r / (1 + exp((b_r - x) / c_r)) + ((a2_r - a_r) / (1 + exp((b2_r - x) / c2_r))))
552+
y <- a_r / (1 + exp((b_r - x) / c_r)) + ((a2_r - a_r) / (1 + exp((b2_r - x) / c2_r)))
553+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r,
554+
"A2" = a2_r, "B2" = b2_r, "C2" = c2_r)))
523555
}
556+
557+
#' @keywords internal
558+
#' @noRd
524559
gsi_doublegompertz <- function(x, pars, noise) {
525560
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
526561
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
527562
c_r <- pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])
528563
a2_r <- pars[["A2"]] + rnorm(1, mean = 0, sd = noise[["A2"]])
529564
b2_r <- pars[["B2"]] + rnorm(1, mean = 0, sd = noise[["B2"]])
530565
c2_r <- pars[["C2"]] + rnorm(1, mean = 0, sd = noise[["C2"]])
531-
return((a_r * exp(-b_r * exp(-c_r * x))) + ((a2_r - a_r) * exp(-b2_r * exp(-c2_r * (x - b_r)))))
566+
y <- (a_r * exp(-b_r * exp(-c_r * x))) + ((a2_r - a_r) * exp(-b2_r * exp(-c2_r * (x - b_r))))
567+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r,
568+
"A2" = a2_r, "B2" = b2_r, "C2" = c2_r)))
532569
}
570+
571+
#' @keywords internal
572+
#' @noRd
533573
gsi_monomolecular <- function(x, pars, noise) {
534574
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
535575
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
536-
return(a_r - a_r * exp(-b_r * x))
576+
y <- a_r - a_r * exp(-b_r * x)
577+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r)))
537578
}
579+
580+
#' @keywords internal
581+
#' @noRd
538582
gsi_exponential <- function(x, pars, noise) {
539583
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
540584
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
541-
return(a_r * exp(b_r * x))
585+
y <- a_r * exp(b_r * x)
586+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r)))
542587
}
588+
589+
#' @keywords internal
590+
#' @noRd
543591
gsi_linear <- function(x, pars, noise) {
544592
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
545-
return(a_r * x)
593+
y <- a_r * x
594+
return(list("y" = y, "pars" = data.frame("A" = a_r)))
546595
}
596+
597+
#' @keywords internal
598+
#' @noRd
547599
gsi_powerlaw <- function(x, pars, noise) {
548600
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
549601
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
550-
return(a_r * x^(b_r))
602+
y <- a_r * x^(b_r)
603+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r)))
551604
}
605+
606+
#' @keywords internal
607+
#' @noRd
552608
gsi_logarithmic <- function(x, pars, noise) {
553609
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
554-
return(a_r * log(x))
610+
y <- a_r * log(x)
611+
return(list("y" = y, "pars" = data.frame("A" = a_r)))
555612
}
613+
614+
#' @keywords internal
615+
#' @noRd
556616
gsi_frechet <- function(x, pars, noise) {
557617
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
558618
b_r <- max(c(0, pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])))
559619
c_r <- max(c(0, pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])))
560620
# holding location to 0, b is shape parameter, c is scale (growth rate)
561-
return(a_r * exp(-((x - 0) / c_r)^(-b_r)))
621+
y <- a_r * exp(-((x - 0) / c_r)^(-b_r))
622+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r)))
562623
}
624+
625+
#' @keywords internal
626+
#' @noRd
563627
gsi_gumbel <- function(x, pars, noise) {
564628
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
565629
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
566630
c_r <- pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])
567631
# b is location, c is scale (rate)
568-
return(a_r * exp(-exp(-(x - b_r) / c_r)))
632+
y <- a_r * exp(-exp(-(x - b_r) / c_r))
633+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r)))
569634
}
635+
636+
#' @keywords internal
637+
#' @noRd
570638
gsi_weibull <- function(x, pars, noise) {
571639
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
572640
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
573641
c_r <- pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])
574642
# c is scale, b is shape
575-
return(a_r * (1 - exp(-(x / c_r)^b_r)))
643+
y <- a_r * (1 - exp(-(x / c_r)^b_r))
644+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r)))
576645
}
646+
647+
#' @keywords internal
648+
#' @noRd
577649
gsi_bragg <- function(x, pars, noise) {
578650
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
579651
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
580652
c_r <- pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])
581653
# a is max response, b is precision, c is x position of max response
582-
return(a_r * exp(-b_r * (x - c_r)^2))
654+
y <- a_r * exp(-b_r * (x - c_r)^2)
655+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r)))
583656
}
657+
658+
#' @keywords internal
659+
#' @noRd
584660
gsi_lorentz <- function(x, pars, noise) {
585661
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
586662
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
587663
c_r <- pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])
588664
# a is max response, b is precision, c is x position of max response
589-
return(a_r / (1 + b_r * (x - c_r)^2))
665+
y <- a_r / (1 + b_r * (x - c_r)^2)
666+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r)))
590667
}
668+
669+
#' @keywords internal
670+
#' @noRd
591671
gsi_beta <- function(x, pars, noise) {
592672
a_r <- pars[["A"]] + rnorm(1, mean = 0, sd = noise[["A"]])
593673
b_r <- pars[["B"]] + rnorm(1, mean = 0, sd = noise[["B"]])
594674
c_r <- pars[["C"]] + rnorm(1, mean = 0, sd = noise[["C"]])
595675
d_r <- pars[["D"]] + rnorm(1, mean = 0, sd = noise[["D"]])
596676
e_r <- pars[["E"]] + rnorm(1, mean = 0, sd = noise[["E"]])
597677
y <- a_r * (((x - d_r) / (c_r - d_r)) * ((e_r - x) / (e_r - c_r))^((e_r - c_r) / (c_r - d_r)))^b_r
598-
return(y)
678+
return(list("y" = y, "pars" = data.frame("A" = a_r, "B" = b_r, "C" = c_r, "D" = d_r, "E" = e_r)))
599679
}

man/growthSim.Rd

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)