From 848513770b535fc5a8d4962d23d05b73eec352b1 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Tue, 11 Apr 2023 11:46:22 +0200 Subject: [PATCH] Streamline and tighten lintr checks (#220) * Replace lint.yaml by lint-changed-file.yaml Copied from r-lib/actions with some extra bells and whistles copied from lint.yaml - triggered on develop and can be triggered manually - can be skipped with the [ci skip] instruction in the commit message * Try to include all linters * Fix some indents Indents in function argument definition have not been changed because they are an explicit style choice * Add fixed = TRUE to calls with fixed regexes * Add leading zero to double * Use toString() rather than paste(collapse = ", ") * Use anyNA() rather than any(is.na()) * Remove unused variables * Pass function directly to sapply instead of creating lambda * Use dedicated lengths() function * Remove unnecessary library() calls * Use file.path() to construct file paths * Replace unnecessary ifelse() by as.numeric() * Remove unnecessary paste0() in warning() and stop() * Remove unnecessary c() * Use seq_len() rather than : * Use sort() rather than order() * Remove nested if * Disable linters that generate too many false positive or that flag explicit style choices that diverge from default * Run devtools::document() * Add NEWS items * Increment version number * Remove extra trailing whitespace --- .github/workflows/lint-changed-files.yaml | 54 +++++++++++++++ .github/workflows/lint.yaml | 36 ---------- .lintr | 22 ++++-- DESCRIPTION | 2 +- NEWS.md | 4 +- R/check.R | 15 +++-- R/epinowcast.R | 4 +- R/formula-tools.R | 82 ++++++++++++----------- R/model-design-tools.R | 6 +- R/model-module-helpers.R | 18 +++-- R/model-modules.R | 36 +++++----- R/model-tools.R | 10 +-- R/model-validation.R | 2 +- R/postprocess.R | 8 +-- R/preprocess.R | 28 ++++---- R/simulate.R | 2 +- R/utils.R | 21 +++--- inst/examples/germany_missing.R | 1 - inst/examples/germany_simple.R | 1 - inst/make_hexsticker.R | 33 ++++----- inst/scripts/generate_examples.R | 8 +-- man/check_by.Rd | 2 +- man/convolution_matrix.Rd | 4 +- man/enw_add_metaobs_features.Rd | 2 +- man/enw_assign_group.Rd | 2 +- man/enw_complete_dates.Rd | 2 +- man/enw_cumulative_to_incidence.Rd | 2 +- man/enw_delay_filter.Rd | 4 +- man/enw_expectation.Rd | 4 +- man/enw_incidence_to_cumulative.Rd | 2 +- man/enw_manual_formula.Rd | 6 +- man/enw_metadata.Rd | 6 +- man/enw_preprocess_data.Rd | 2 +- man/enw_reps_with_complete_refs.Rd | 2 +- man/enw_simulate_missing_reference.Rd | 2 +- man/epinowcast.Rd | 2 +- vignettes/precompile.R | 4 +- 37 files changed, 236 insertions(+), 205 deletions(-) create mode 100644 .github/workflows/lint-changed-files.yaml delete mode 100644 .github/workflows/lint.yaml diff --git a/.github/workflows/lint-changed-files.yaml b/.github/workflows/lint-changed-files.yaml new file mode 100644 index 000000000..ebb7e6cd6 --- /dev/null +++ b/.github/workflows/lint-changed-files.yaml @@ -0,0 +1,54 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: + - main + - master + - develop + pull_request: + branches: + - main + - master + - develop + workflow_dispatch: + +name: lint-changed-files + +jobs: + lint-changed-files: + runs-on: ubuntu-latest + if: "! contains(github.event.head_commit.message, '[ci skip]')" + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v3 + + - uses: r-lib/actions/setup-r@v2 + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: | + any::gh + any::lintr + any::purrr + needs: check + + - name: Add lintr options + run: | + cat('\noptions(lintr.linter_file = ".lintr")\n', file = "~/.Rprofile", append = TRUE) + shell: Rscript {0} + + - name: Install package + run: R CMD INSTALL . + + - name: Extract and lint files changed by this PR + run: | + files <- gh::gh("GET https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files") + changed_files <- purrr::map_chr(files, "filename") + all_files <- list.files(recursive = TRUE) + exclusions_list <- as.list(setdiff(all_files, changed_files)) + lintr::lint_package(exclusions = exclusions_list) + shell: Rscript {0} + env: + LINTR_ERROR_ON_LINT: true diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml deleted file mode 100644 index 0c602d3e1..000000000 --- a/.github/workflows/lint.yaml +++ /dev/null @@ -1,36 +0,0 @@ -on: - push: - branches: - - main - - master - - develop - pull_request: - branches: - - main - - master - - develop - workflow_dispatch: - -name: lint - -jobs: - lint: - runs-on: ubuntu-latest - if: "! contains(github.event.head_commit.message, '[ci skip]')" - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - steps: - - uses: actions/checkout@v2 - - - uses: r-lib/actions/setup-r@v2 - with: - use-public-rspm: true - - - uses: r-lib/actions/setup-r-dependencies@v2 - with: - extra-packages: any::lintr - needs: lint - - - name: Lint - run: lintr::lint_package() - shell: Rscript {0} diff --git a/.lintr b/.lintr index 9e50e0528..83004a275 100644 --- a/.lintr +++ b/.lintr @@ -1,7 +1,15 @@ -linters: linters_with_defaults( - line_length_linter = line_length_linter(80), - cyclocomp_linter = cyclocomp_linter(complexity_limit = 20L), - object_usage_linter = NULL) -exclusions: c(list.files(path = "tests/", recursive = T, full.names = T), - "vignettes/germany-age-stratified-nowcasting.Rmd.orig") -exclude: "# nolint" +linters: linters_with_tags( + tags = NULL, # include all linters + implicit_integer_linter = NULL, + extraction_operator_linter = NULL, + undesirable_function_linter = NULL, + function_argument_linter = NULL, + indentation_linter = NULL, + object_name_linter = NULL, + cyclocomp_linter(25L) + ) +exclusions: c( + list.files("tests", recursive = TRUE, full.names = TRUE), + list.files("inst", recursive = TRUE, full.names = TRUE), + "vignettes/germany-age-stratified-nowcasting.Rmd.orig" + ) diff --git a/DESCRIPTION b/DESCRIPTION index 0e7c073cd..7dcc3ab89 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: epinowcast Title: Flexible Hierarchical Nowcasting -Version: 0.2.0.7000 +Version: 0.2.0.8000 Authors@R: c(person(given = "Sam Abbott", role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index 7bafd9796..d97d5463b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# epinowcast 0.2.0.7000 +# epinowcast 0.2.0.8000 This is release is in development. It is not yet ready for production use. If you notice problems please report them on the [issue tracker](https://github.com/epinowcast/epinowcast/issues). @@ -9,6 +9,8 @@ This is release is in development. It is not yet ready for production use. If yo ## Package +- Added more non-default linters in `.lintr` configuration file. This file is used when `lintr::lint_package()` is run or in the new `lint-changed-files.yaml` GitHub Actions workflow. See #220 by @Bisaloo and reviewed by @pearsonca and @seeabs. +- Switched to the `lint-changed-files.yaml` GitHub Actions workflow instead of the regular `lint.yaml` to avoid annotations unrelated to the changes made in the PR. See #220 by @Bisaloo and reviewed by @pearsonca and @seeabs. - Added tests for `summary.epinowcast()` and `plot.epinowcast()` methods. See #209 by @seabbs and reviewed by @pearsonca. - Added tests for `enw_plot_obs()` where not otherwise covered by `plot.epinowcast()` tests. See #209 by @seabbs and reviewed by @pearsonca. - Made the `.group` variable optional for all preprocessing functions using a new `add_group()` internal function. See #208 by @seabbs and reviewed by @pearsonca. diff --git a/R/check.R b/R/check.R index 33bcae95a..e55f3de64 100644 --- a/R/check.R +++ b/R/check.R @@ -17,7 +17,7 @@ check_quantiles <- function(posterior, req_probs = c(0.5, 0.95, 0.2, 0.8)) { if (sum(cols %in% paste0("q", req_probs * 100)) != length(req_probs)) { stop( "Following quantiles must be present (set with probs): ", - paste(req_probs, collapse = ", ") + toString(req_probs) ) } return(invisible(NULL)) @@ -88,7 +88,7 @@ check_group <- function(obs) { #' @return NULL #' #' @family check -check_by <- function(obs, by = c()) { +check_by <- function(obs, by = NULL) { if (length(by) > 0) { if (!is.character(by)) { stop("`by` must be a character vector") @@ -96,8 +96,8 @@ check_by <- function(obs, by = c()) { if (!all(by %in% colnames(obs))) { stop( "`by` must be a subset of the columns in `obs`. \n", - paste0(paste(by[!(by %in% colnames(obs))], collapse = ", "), - " are not present in `obs`") + toString(by[!(by %in% colnames(obs))]), + " are not present in `obs`" ) } } @@ -151,15 +151,16 @@ check_modules_compatible <- function(modules) { modules[[4]]$data$model_miss && !modules[[6]]$data$likelihood_aggregation ) { - warning(paste0( + warning( "Incompatible model specification: A missingness model has ", "been specified but likelihood aggregation is specified as ", "by snapshot. Switching to likelihood aggregation by group.", " This has no effect on the nowcast but limits the ", "number of threads per chain to the number of groups. To ", "silence this warning, set the `likelihood_aggregation` ", - "argument in `enw_fit_opts` to 'groups'." - ), immediate. = TRUE) + "argument in `enw_fit_opts` to 'groups'.", + immediate. = TRUE + ) } return(invisible(NULL)) } diff --git a/R/epinowcast.R b/R/epinowcast.R index 3ea399e34..ad6b681ad 100644 --- a/R/epinowcast.R +++ b/R/epinowcast.R @@ -115,9 +115,9 @@ epinowcast <- function(data, ), expectation = epinowcast::enw_expectation( r = ~ 0 + (1 | day:.group), - generation_time = c(1), + generation_time = 1, observation = ~1, - latent_reporting_delay = c(1), + latent_reporting_delay = 1, data = data ), missing = epinowcast::enw_missing( diff --git a/R/formula-tools.R b/R/formula-tools.R index 2821c86e6..77e03299c 100644 --- a/R/formula-tools.R +++ b/R/formula-tools.R @@ -36,14 +36,14 @@ #' @examples #' data <- enw_example("prep")$metareference[[1]] #' enw_manual_formula(data, fixed = "week", random = "day_of_week") -enw_manual_formula <- function(data, fixed = c(), random = c(), - custom_random = c(), no_contrasts = FALSE, +enw_manual_formula <- function(data, fixed = NULL, random = NULL, + custom_random = NULL, no_contrasts = FALSE, add_intercept = TRUE) { data <- data.table::copy(data) if (add_intercept) { - form <- c("1") + form <- "1" } else { - form <- c() + form <- NULL } cr_in_dt <- purrr::map( @@ -103,8 +103,8 @@ as_string_formula <- function(formula) { #' epinowcast:::split_formula_to_terms(~ 1 + age_group + location) split_formula_to_terms <- function(formula) { formula <- as_string_formula(formula) - formula <- gsub("~", "", formula) - formula <- strsplit(formula, " \\+ ")[[1]] + formula <- gsub("~", "", formula, fixed = TRUE) + formula <- strsplit(formula, " + ", fixed = TRUE)[[1]] return(formula) } @@ -134,7 +134,7 @@ rw_terms <- function(formula) { match <- grepl("(^(rw)\\([^:]*\\))$", trms) # ignore when included in a random effects term - match <- match & !grepl("\\|", trms) + match <- match & !grepl("|", trms, fixed = TRUE) return(trms[match]) } @@ -259,7 +259,7 @@ rw <- function(time, by, type = c("independent", "dependent")) { by <- deparse(substitute(by)) } out <- list(time = time, by = by, type = type) - class(out) <- c("enw_rw_term") + class(out) <- "enw_rw_term" return(out) } @@ -374,11 +374,9 @@ construct_rw <- function(rw, data) { #' form <- epinowcast:::parse_formula(~ 1 + (location | age_group)) #' re(form$random[[1]]) re <- function(formula) { - terms <- strsplit(as_string_formula(formula), " \\| ")[[1]] - fixed <- terms[1] - random <- terms[2] + terms <- strsplit(as_string_formula(formula), " | ", fixed = TRUE)[[1]] out <- list(fixed = terms[1], random = terms[2]) - class(out) <- c("enw_re_term") + class(out) <- "enw_re_term" return(out) } @@ -423,14 +421,14 @@ construct_re <- function(re, data) { data <- data.table::as.data.table(data) # extract random and fixed effects - fixed <- strsplit(re$fixed, " \\+ ")[[1]] - random <- strsplit(re$random, " \\+ ")[[1]] + fixed <- strsplit(re$fixed, " + ", fixed = TRUE)[[1]] + random <- strsplit(re$random, " + ", fixed = TRUE)[[1]] # expand random effects that are interactions - expanded_random <- c() + expanded_random <- NULL random_int <- rep(FALSE, length(random)) for (i in seq_along(random)) { - current_random <- strsplit(random[i], ":")[[1]] + current_random <- strsplit(random[i], ":", fixed = TRUE)[[1]] if (length(current_random) > 1) { if (length(current_random) > 2) { @@ -439,12 +437,12 @@ construct_re <- function(re, data) { ) } if (length(unique(data[[current_random[2]]])) < 2) { - message( - "A random effect using ", current_random[2], - " is not possible as this variable has fewer than 2 unique values." - ) - random[i] <- current_random[1] - }else { + message( + "A random effect using ", current_random[2], + " is not possible as this variable has fewer than 2 unique values." + ) + random[i] <- current_random[1] + } else { random_int[i] <- TRUE } } @@ -458,20 +456,21 @@ construct_re <- function(re, data) { # add these new random effects to list of all random effects # combine into fixed effects terms - terms <- c() - terms_int <- c() + terms <- NULL + terms_int <- NULL for (i in seq_along(random)) { terms <- c(terms, paste0(fixed, ":", random[i])) terms_int <- c(terms_int, rep(random_int[i], length(fixed))) } names(terms_int) <- terms - terms <- gsub("1:", "", terms) + terms <- gsub("1:", "", terms, fixed = TRUE) terms <- terms[!startsWith(terms, "0:")] terms_int <- terms_int[!startsWith(terms, "0:")] # make all right hand side random effects factors data <- data[, - (expanded_random) := lapply(.SD, as.factor), .SDcols = expanded_random + (expanded_random) := lapply(.SD, as.factor), + .SDcols = expanded_random ] # make a fixed effects design matrix @@ -486,14 +485,14 @@ construct_re <- function(re, data) { # implement random effects structure for (i in seq_along(terms)) { - loc_terms <- strsplit(terms[i], ":")[[1]] + loc_terms <- strsplit(terms[i], ":", fixed = TRUE)[[1]] # expand right hand side random effect if its an interaction # and make a list to map to effects if (terms_int[i]) { expanded_int <- unique(data[[loc_terms[length(loc_terms)]]]) expanded_int <- paste0(loc_terms[length(loc_terms)], expanded_int) j <- purrr::map(expanded_int, function(x) { - j <- c() + j <- NULL if (length(loc_terms) > 2) { j <- loc_terms[1:(length(loc_terms) - 2)] } @@ -510,19 +509,21 @@ construct_re <- function(re, data) { if (length(k) == 1) { if (terms_int[i]) { effects <- enw_add_pooling_effect( - effects, var_name = gsub(":", "__", k), + effects, var_name = gsub(":", "__", k, fixed = TRUE), finder_fn = function(effect, pattern) { grepl(pattern[1], effect) & - grepl(pattern[2], effect, fixed = TRUE) & - lengths(regmatches(effect, gregexpr(":", effect))) == 1 + grepl(pattern[2], effect, fixed = TRUE) & + lengths( + regmatches(effect, gregexpr(":", effect, fixed = TRUE)) + ) == 1 }, - pattern = strsplit(k, ":")[[1]] + pattern = strsplit(k, ":", fixed = TRUE)[[1]] ) } else { effects <- enw_add_pooling_effect( effects, var_name = k, finder_fn = function(effect, pattern) { - grepl(pattern, effect) & !grepl(":", effect) + grepl(pattern, effect) & !grepl(":", effect, fixed = TRUE) }, pattern = k ) @@ -530,12 +531,13 @@ construct_re <- function(re, data) { } else { if (terms_int[i]) { effects <- enw_add_pooling_effect( - effects, var_name = paste(gsub(":", "__", k), collapse = "__"), - finder_fn = function(effect, pattern) { - grepl(pattern[1], effect) & grepl(pattern[2], effect) & - grepl(pattern[3], effect) + effects, + var_name = paste(gsub(":", "__", k, fixed = TRUE), collapse = "__"), + finder_fn = function(effect, pattern) { + grepl(pattern[1], effect) & grepl(pattern[2], effect) & + grepl(pattern[3], effect) }, - pattern = c(k[1], strsplit(k[-1], ":")[[1]]) + pattern = c(k[1], strsplit(k[-1], ":", fixed = TRUE)[[1]]) ) } else { effects <- enw_add_pooling_effect( @@ -635,7 +637,7 @@ enw_formula <- function(formula, data, sparse = TRUE) { no_contrasts <- random_terms } else { no_contrasts <- FALSE - random_terms <- c() + random_terms <- NULL random_metadata <- NULL } @@ -658,7 +660,7 @@ enw_formula <- function(formula, data, sparse = TRUE) { use.names = TRUE, fill = TRUE ) } else { - rw_terms <- c() + rw_terms <- NULL rw_metadata <- NULL } diff --git a/R/model-design-tools.R b/R/model-design-tools.R index e1cb84981..fb97d83d9 100644 --- a/R/model-design-tools.R +++ b/R/model-design-tools.R @@ -74,7 +74,7 @@ enw_design <- function(formula, data, no_contrasts = FALSE, sparse = TRUE, data <- data.table::as.data.table(data) # make all character variables factors - chars <- colnames(data)[sapply(data, function(x) is.character(x))] + chars <- colnames(data)[sapply(data, is.character)] data <- suppressWarnings( data[, (chars) := lapply(.SD, as.factor), .SDcols = chars] ) @@ -193,7 +193,7 @@ enw_effects_metadata <- function(design) { enw_add_pooling_effect <- function(effects, var_name = "sd", finder_fn = startsWith, ...) { effects <- data.table::setDT(effects) - effects[, (var_name) := ifelse(finder_fn(effects, ...), 1, 0)] + effects[, (var_name) := as.numeric(finder_fn(effects, ...))] effects[finder_fn(effects, ...), fixed := 0] return(effects[]) } @@ -247,7 +247,7 @@ enw_add_cumulative_membership <- function(metaobs, feature) { metaobs[, (paste0(cfeature, as.character(min_avail))) := NULL] cfeatures <- grep(cfeature, colnames(metaobs), value = TRUE) metaobs[, - (cfeatures) := purrr::map(.SD, ~ ifelse(cumsum(.) > 0, 1, 0)), + (cfeatures) := purrr::map(.SD, ~ as.numeric(cumsum(.) > 0)), .SDcols = cfeatures, by = ".group" ] } diff --git a/R/model-module-helpers.R b/R/model-module-helpers.R index 394970f85..ffee4862b 100644 --- a/R/model-module-helpers.R +++ b/R/model-module-helpers.R @@ -8,7 +8,7 @@ #' variables specified for report dates that have complete reporting. #' @inheritParams enw_preprocess_data #' @family modelmodulehelpers -enw_reps_with_complete_refs <- function(new_confirm, max_delay, by = c()) { +enw_reps_with_complete_refs <- function(new_confirm, max_delay, by = NULL) { check_by(new_confirm, by = by) rep_with_complete_ref <- data.table::as.data.table(new_confirm) rep_with_complete_ref <- rep_with_complete_ref[, @@ -51,7 +51,7 @@ enw_reference_by_report <- function(missing_reference, reps_with_complete_refs, data.table::setkeyv(miss_lk, c(".group", "reference_date", "report_date")) # Assign an index (this should link with the in model index) - miss_lk[, .id := 1:.N] + miss_lk[, .id := seq_len(.N)] # Link with reports with complete reference dates complete_miss_lk <- miss_lk[ @@ -111,19 +111,19 @@ latest_obs_as_matrix <- function(latest) { #' # Include partially reported convolutions #' convolution_matrix(c(1, 2, 3), 10, include_partial = TRUE) #' # Use a list of distributions -#' convolution_matrix(rep(list(c(1, 2, 3)), 10),10) +#' convolution_matrix(rep(list(c(1, 2, 3)), 10), 10) #' # Use a time-varying list of distributions -#' convolution_matrix(c(rep(list(c(1, 2, 3)), 10), list(c(4,5,6))), 11) +#' convolution_matrix(c(rep(list(c(1, 2, 3)), 10), list(c(4, 5, 6))), 11) convolution_matrix <- function(dist, t, include_partial = FALSE) { if (is.list(dist)) { if (length(dist) != t) { stop("dist must equal t or be the same for all t (i.e. length 1)") } - ldist <- purrr::map_dbl(dist, length) + ldist <- lengths(dist) if (!all(ldist == ldist[1])) { stop("dist must be the same length for all t") } - }else { + } else { ldist <- rep(length(dist), t) dist <- rep(list(dist), t) } @@ -132,10 +132,8 @@ convolution_matrix <- function(dist, t, include_partial = FALSE) { l <- min(t - s + 1, ldist[s]) conv[s:(s + l - 1), s] <- head(dist[[s]], l) } - if (!include_partial) { - if (ldist[1] > 1) { - conv[1:(ldist[1] - 1), ] <- 0 - } + if (!include_partial && ldist[1] > 1) { + conv[1:(ldist[1] - 1), ] <- 0 } return(conv) } diff --git a/R/model-modules.R b/R/model-modules.R index 0400c4252..a1cd19f46 100644 --- a/R/model-modules.R +++ b/R/model-modules.R @@ -188,9 +188,9 @@ enw_report <- function(non_parametric = ~0, structural = ~0, data) { out$formula$non_parametric <- form$formula out$data <- data_list out$priors <- data.table::data.table( - variable = c("rep_beta_sd"), - description = c("Standard deviation of scaled pooled report date effects"), - distribution = c("Zero truncated normal"), + variable = "rep_beta_sd", + description = "Standard deviation of scaled pooled report date effects", + distribution = "Zero truncated normal", mean = 0, sd = 1 ) @@ -258,8 +258,8 @@ enw_report <- function(non_parametric = ~0, structural = ~0, data) { #' @export #' @examples #' enw_expectation(data = enw_example("preprocessed")) -enw_expectation <- function(r = ~ 0 + (1 | day:.group), generation_time = c(1), - observation = ~1, latent_reporting_delay = c(1), +enw_expectation <- function(r = ~ 0 + (1 | day:.group), generation_time = 1, + observation = ~1, latent_reporting_delay = 1, data, ...) { if (as_string_formula(r) %in% "~0") { stop("An expectation model formula for r must be specified") @@ -317,7 +317,8 @@ enw_expectation <- function(r = ~ 0 + (1 | day:.group), generation_time = c(1), length(latent_reporting_delay[[1]]), length(latent_reporting_delay) ), lrd = convolution_matrix( - latent_reporting_delay, r_list$ft, include_partial = FALSE + latent_reporting_delay, r_list$ft, + include_partial = FALSE ) ) @@ -325,10 +326,9 @@ enw_expectation <- function(r = ~ 0 + (1 | day:.group), generation_time = c(1), obs_list <- c(obs_list, extract_sparse_matrix(obs_list$lrd, prefix = "lrd")) obs_list$lrd <- NULL - obs_list$obs <- ifelse( - sum(latent_reporting_delay) == 1 && obs_list$lrd_n == 1 && - as_string_formula(observation) %in% "~1", - 0, 1 + obs_list$obs <- as.numeric( + sum(latent_reporting_delay) != 1 || obs_list$lrd_n != 1 || + !as_string_formula(observation) %in% "~1" ) # Observation formula obs_form <- enw_formula(observation, data$metareference[[1]], sparse = FALSE) @@ -470,9 +470,9 @@ enw_missing <- function(formula = ~1, data) { # Get the indexes for when grouped observations start and end miss_lookup <- data.table::copy(rep_w_complete_ref) - data_list$miss_st <- miss_lookup[, n := 1:.N, by = ".group"] + data_list$miss_st <- miss_lookup[, n := seq_len(.N), by = ".group"] data_list$miss_st <- data_list$miss_st[, .(n = max(n)), by = ".group"]$n - data_list$miss_cst <- miss_lookup[, n := 1:.N] + data_list$miss_cst <- miss_lookup[, n := seq_len(.N)] data_list$miss_cst <- data_list$miss_cst[, .(n = max(n)), by = ".group"]$n # Get (and order) reported cases with a missing reference date @@ -582,7 +582,7 @@ enw_obs <- function(family = c("negbin", "poisson"), data) { # snap lookup snap_lookup <- unique(new_confirm[, .(reference_date, .group)]) - snap_lookup[, s := 1:.N] + snap_lookup[, s := seq_len(.N)] snap_lookup <- data.table::dcast( snap_lookup, reference_date ~ .group, value.var = "s" @@ -591,7 +591,7 @@ enw_obs <- function(family = c("negbin", "poisson"), data) { # snap time snap_time <- unique(new_confirm[, .(reference_date, .group)]) - snap_time[, t := 1:.N, by = ".group"] + snap_time[, t := seq_len(.N), by = ".group"] snap_time <- snap_time$t # Format indexing and observed data @@ -610,7 +610,7 @@ enw_obs <- function(family = c("negbin", "poisson"), data) { dmax = data$max_delay[[1]], sdmax = rep(data$max_delay[[1]], data$snapshots[[1]]), csdmax = cumsum(rep(data$max_delay[[1]], data$snapshots[[1]])), - obs = as.matrix(data$reporting_triangle[[1]][, -c(1:2)]), + obs = as.matrix(data$reporting_triangle[[1]][, -(1:2)]), flat_obs = flat_obs, latest_obs = latest_matrix, model_obs = model_obs @@ -620,9 +620,9 @@ enw_obs <- function(family = c("negbin", "poisson"), data) { out$family <- family out$data <- data out$priors <- data.table::data.table( - variable = c("sqrt_phi"), - description = c("One over the square root of the reporting overdispersion"), - distribution = c("Zero truncated normal"), + variable = "sqrt_phi", + description = "One over the square root of the reporting overdispersion", + distribution = "Zero truncated normal", mean = 0, sd = 1 ) diff --git a/R/model-tools.R b/R/model-tools.R index 2fe6377f8..2d5dd3a2e 100644 --- a/R/model-tools.R +++ b/R/model-tools.R @@ -41,8 +41,9 @@ enw_formula_as_data_list <- function(formula, prefix, enw_formula" ) } - fintercept <- as.numeric(any(grepl( - "(Intercept)", colnames(formula$fixed$design), fixed = TRUE + fintercept <- as.numeric(any(grepl( + "(Intercept)", colnames(formula$fixed$design), + fixed = TRUE ))) data <- list() @@ -328,12 +329,13 @@ enw_model <- function(model = system.file( cpp_options = list(), verbose = TRUE, ...) { if (verbose) { message(sprintf("Using model %s.", model)) - message(sprintf("include is %s.", paste(include, collapse = ", "))) + message(sprintf("include is %s.", toString(include))) } if (!profile) { stan_no_profile <- write_stan_files_no_profile( - model, include, target_dir = target_dir + model, include, + target_dir = target_dir ) model <- stan_no_profile$model include <- stan_no_profile$include_paths diff --git a/R/model-validation.R b/R/model-validation.R index 51de40842..4dce6f529 100644 --- a/R/model-validation.R +++ b/R/model-validation.R @@ -58,7 +58,7 @@ enw_score_nowcast <- function(nowcast, latest_obs, log = FALSE, } long_nowcast <- enw_quantiles_to_long(nowcast) if (!is.null(long_nowcast[["mad"]])) { - long_nowcast[, c("mad") := NULL] + long_nowcast[, "mad" := NULL] } latest_obs <- data.table::copy(latest_obs) data.table::setnames(latest_obs, "confirm", "true_value", skip_absent = TRUE) diff --git a/R/postprocess.R b/R/postprocess.R index 31f9d094f..f2a3b29be 100644 --- a/R/postprocess.R +++ b/R/postprocess.R @@ -29,9 +29,7 @@ enw_posterior <- function(fit, variables = NULL, probs = c(0.05, 0.2, 0.8, 0.95), ...) { # order probs - probs <- probs[order(probs)] - # NULL out variables - variable <- type <- NULL + probs <- sort(probs, na.last = TRUE) # extract summary parameters of interest and join sfit <- list( @@ -62,7 +60,7 @@ enw_posterior <- function(fit, variables = NULL, #' #' @description A generic wrapper around [enw_posterior()] with #' opinionated defaults to extract the posterior prediction for the -#' nowcast (`"pp_inf_obs"` from the `stan` code). The functionality of +#' nowcast (`"pp_inf_obs"` from the `stan` code). The functionality of #' this function can be used directly on the output of [epinowcast()] using #' the supplied [summary.epinowcast()] method. #' @@ -310,7 +308,7 @@ enw_quantiles_to_long <- function(posterior) { measure.vars = patterns("^q[0-9]"), value.name = "prediction", variable.name = "quantile" ) - long[, quantile := gsub("q", "", quantile)] + long[, quantile := gsub("q", "", quantile, fixed = TRUE)] long[, quantile := as.numeric(quantile) / 100] return(long[]) } diff --git a/R/preprocess.R b/R/preprocess.R index ed111eb02..d56794c92 100644 --- a/R/preprocess.R +++ b/R/preprocess.R @@ -5,9 +5,9 @@ #' (reference or report), `confirm`, `max_confirm``, and `cum_prop_reported` #' are dropped and the first observation for each group and date is retained. #' -#' @param obs A `data.frame` or `data.table` with columns: `reference_date` and/or -#' `report_date`; at least one must be provided, `.group`, a grouping column -#' and a `date`, a [Date] column. +#' @param obs A `data.frame` or `data.table` with columns: `reference_date` +#' and/or `report_date`; at least one must be provided, `.group`, a grouping +#' column and a `date`, a [Date] column. #' #' @param target_date A character string, either "reference_date" or #' "report_date". The column corresponding to this string will be used @@ -114,7 +114,7 @@ enw_metadata <- function(obs, target_date = c( #' holidaymeta #' subset(holidaymeta, day_of_week == "Holiday") enw_add_metaobs_features <- function(metaobs, - holidays = c(), + holidays = NULL, holidays_to = "Sunday", datecol = "date") { # localize and check metaobs input @@ -270,7 +270,7 @@ enw_extend_date <- function(metaobs, days = 20, direction = "end") { #' obs <- data.frame(x = 1:3, y = 1:3) #' enw_assign_group(obs) #' enw_assign_group(obs, by = "x") -enw_assign_group <- function(obs, by = c()) { +enw_assign_group <- function(obs, by = NULL) { if (!is.null(obs[[".group"]])) { stop( "The `.group` column is reserved for internal use. Please remove it ", @@ -282,7 +282,7 @@ enw_assign_group <- function(obs, by = c()) { if (length(by) != 0) { groups_index <- data.table::copy(obs) groups_index <- unique(groups_index[, ..by]) - groups_index[, .group := 1:.N] + groups_index[, .group := seq_len(.N)] obs <- merge(obs, groups_index, by = by, all.x = TRUE) } else { obs <- add_group(obs) @@ -478,7 +478,7 @@ enw_latest_data <- function(obs) { latest_data <- latest_data[, .SD[report_date == (max(report_date)) | is.na(reference_date)], - by = c("reference_date") + by = "reference_date" ] latest_data <- latest_data[!is.na(reference_date)] return(latest_data[]) @@ -513,7 +513,7 @@ enw_latest_data <- function(obs) { #' dt <- enw_add_max_reported(dt) #' enw_cumulative_to_incidence(dt) enw_cumulative_to_incidence <- function(obs, set_negatives_to_zero = TRUE, - by = c()) { + by = NULL) { check_by(obs) reports <- check_dates(obs) data.table::setkeyv(reports, c(by, "reference_date", "report_date")) @@ -556,7 +556,7 @@ enw_cumulative_to_incidence <- function(obs, set_negatives_to_zero = TRUE, #' dt <- enw_assign_group(dt) #' dt <- enw_add_max_reported(dt) #' enw_cumulative_to_incidence(dt) -enw_incidence_to_cumulative <- function(obs, by = c()) { +enw_incidence_to_cumulative <- function(obs, by = NULL) { obs <- check_dates(obs) check_by(obs) @@ -569,8 +569,8 @@ enw_incidence_to_cumulative <- function(obs, by = c()) { #' Filter observations to restrict the maximum reporting delay #' -#' @return A `data.frame` filtered so that dates by report are less than or equal -#' the reference date plus the maximum delay. +#' @return A `data.frame` filtered so that dates by report are less than or +#' equal the reference date plus the maximum delay. #' #' @inheritParams enw_cumulative_to_incidence #' @inheritParams enw_preprocess_data @@ -679,7 +679,7 @@ enw_reporting_triangle_to_long <- function(obs) { #' confirm = 1 #' ) #' enw_complete_dates(obs) -enw_complete_dates <- function(obs, by = c(), max_delay, +enw_complete_dates <- function(obs, by = NULL, max_delay, missing_reference = TRUE) { obs <- data.table::as.data.table(obs) obs <- check_dates(obs) @@ -700,7 +700,7 @@ enw_complete_dates <- function(obs, by = c(), max_delay, dates <- as.IDate(dates) obs <- enw_assign_group(obs, by = by) - by_with_group_id <- c(".group", by) + by_with_group_id <- c(".group", by) # nolint: object_usage_linter groups <- unique(obs[, ..by_with_group_id]) completion <- data.table::CJ( @@ -973,7 +973,7 @@ enw_construct_data <- function(obs, new_confirm, latest, missing_reference, #' # Preprocess with default settings #' pobs <- enw_preprocess_data(nat_germany_hosp) #' pobs -enw_preprocess_data <- function(obs, by = c(), max_delay = 20, +enw_preprocess_data <- function(obs, by = NULL, max_delay = 20, set_negatives_to_zero = TRUE, ...) { obs <- check_dates(obs) diff --git a/R/simulate.R b/R/simulate.R index cfc5e9cac..d02192e16 100644 --- a/R/simulate.R +++ b/R/simulate.R @@ -36,7 +36,7 @@ #' nat_germany_hosp, #' proportion = 0.35, by = c("location", "age_group") #' ) -enw_simulate_missing_reference <- function(obs, proportion = 0.2, by = c()) { +enw_simulate_missing_reference <- function(obs, proportion = 0.2, by = NULL) { obs <- enw_cumulative_to_incidence(obs, by = by) obs[, missing := purrr::map2_dbl( diff --git a/R/utils.R b/R/utils.R index b466faf39..43b3be3da 100644 --- a/R/utils.R +++ b/R/utils.R @@ -23,11 +23,12 @@ is.Date <- function(x) { stan_fns_as_string <- function(files, target_dir) { functions <- paste0( "\n functions{ \n", - paste(purrr::map_chr( - files, - ~ paste(readLines(file.path(target_dir, .)), collapse = "\n") - ), - collapse = "\n" + paste( + purrr::map_chr( + files, + ~ paste(readLines(file.path(target_dir, .)), collapse = "\n") + ), + collapse = "\n" ), "\n }" ) @@ -42,10 +43,12 @@ stan_fns_as_string <- function(files, target_dir) { #' @return A character string of stan functions converted for use in `rstan`. #' @family utils convert_cmdstan_to_rstan <- function(functions) { + # nolint start: nonportable_path_linter # replace bars in CDF with commas functions <- gsub("_cdf\\(([^ ]+) *\\|([^)]+)\\)", "_cdf(\\1,\\2)", functions) + # nolint end # replace lupmf with lpmf - functions <- gsub("_lupmf", "_lpmf", functions) + functions <- gsub("_lupmf", "_lpmf", functions, fixed = TRUE) # replace array syntax # case 1a: array[] real x -> real[] x functions <- gsub( @@ -200,12 +203,12 @@ coerce_date <- function(dates) { ) }, FUN.VALUE = data.table::as.IDate(0))) - if (any(is.na(res))) { + if (anyNA(res)) { bads <- is.na(res) stop(sprintf( "Failed to parse with `as.IDate`: {%s} (indices {%s}).", - paste(dates[bads], collapse = ", "), - paste(which(bads), collapse = ", ") + toString(dates[bads]), + toString(which(bads)) )) } else { return(res) diff --git a/inst/examples/germany_missing.R b/inst/examples/germany_missing.R index 168052bfa..5342cff5a 100644 --- a/inst/examples/germany_missing.R +++ b/inst/examples/germany_missing.R @@ -1,7 +1,6 @@ # Load packages library(epinowcast) library(data.table) -library(purrr) library(ggplot2) # Use 4 cores diff --git a/inst/examples/germany_simple.R b/inst/examples/germany_simple.R index bc3dc00b0..a97b11cd3 100644 --- a/inst/examples/germany_simple.R +++ b/inst/examples/germany_simple.R @@ -1,7 +1,6 @@ # Load packages library(epinowcast) library(data.table) -library(ggplot2) # Use 2 cores options(mc.cores = 2) diff --git a/inst/make_hexsticker.R b/inst/make_hexsticker.R index 75112ce83..7ccfbb0d4 100644 --- a/inst/make_hexsticker.R +++ b/inst/make_hexsticker.R @@ -13,8 +13,8 @@ obs <- enw_example("observations") # make standard plot plot <- summary(nowcast)[, mean := NA] |> enw_plot_nowcast_quantiles( - latest = obs[reference_date >= (max(reference_date) - 19)] -) + latest = obs[reference_date >= (max(reference_date) - 19)] + ) # strip out most of the background hex_plot <- plot + @@ -27,18 +27,19 @@ hex_plot <- plot + panel.background = element_blank()) # make and save hexsticker -sticker(hex_plot, - package = "epinowcast", - p_size = 23, - p_color = "#646770", - s_x = 1, - s_y = .85, - s_width = 1.3, - s_height = 0.85, - h_fill = "#ffffff", - h_color = "#646770", - filename = "./man/figures/logo.png", - url = "epinowcast.org", - u_color = "#646770", - u_size = 3.5 +sticker( + hex_plot, + package = "epinowcast", + p_size = 23, + p_color = "#646770", + s_x = 1, + s_y = 0.85, + s_width = 1.3, + s_height = 0.85, + h_fill = "#ffffff", + h_color = "#646770", + filename = file.path("man", "figures", "logo.png"), + url = "epinowcast.org", + u_color = "#646770", + u_size = 3.5 ) diff --git a/inst/scripts/generate_examples.R b/inst/scripts/generate_examples.R index 5866ade48..63dbc52b5 100644 --- a/inst/scripts/generate_examples.R +++ b/inst/scripts/generate_examples.R @@ -1,5 +1,5 @@ -source("inst/examples/germany_dow.R") +source(file.path("inst", "examples", "germany_dow.R")) -saveRDS(nowcast, "inst/extdata/nowcast.rds") -saveRDS(pobs, "inst/extdata/preprocessed_observations.rds") -saveRDS(latest_obs, "inst/extdata/observations.rds") +saveRDS(nowcast, file.path("inst", "extdata", "nowcast.rds")) +saveRDS(pobs, file.path("inst", "extdata", "preprocessed_observations.rds")) +saveRDS(latest_obs, file.path("inst", "extdata", "observations.rds")) diff --git a/man/check_by.Rd b/man/check_by.Rd index feddcfffd..fa2f2dad5 100644 --- a/man/check_by.Rd +++ b/man/check_by.Rd @@ -4,7 +4,7 @@ \alias{check_by} \title{Check by variables are present in the data} \usage{ -check_by(obs, by = c()) +check_by(obs, by = NULL) } \arguments{ \item{obs}{An observation \code{data.frame}.} diff --git a/man/convolution_matrix.Rd b/man/convolution_matrix.Rd index 06a2075eb..31be9848f 100644 --- a/man/convolution_matrix.Rd +++ b/man/convolution_matrix.Rd @@ -32,9 +32,9 @@ convolution_matrix(c(1, 2, 3), 10) # Include partially reported convolutions convolution_matrix(c(1, 2, 3), 10, include_partial = TRUE) # Use a list of distributions -convolution_matrix(rep(list(c(1, 2, 3)), 10),10) +convolution_matrix(rep(list(c(1, 2, 3)), 10), 10) # Use a time-varying list of distributions -convolution_matrix(c(rep(list(c(1, 2, 3)), 10), list(c(4,5,6))), 11) +convolution_matrix(c(rep(list(c(1, 2, 3)), 10), list(c(4, 5, 6))), 11) } \seealso{ Helper functions for model modules diff --git a/man/enw_add_metaobs_features.Rd b/man/enw_add_metaobs_features.Rd index 2ee29d557..b27da4874 100644 --- a/man/enw_add_metaobs_features.Rd +++ b/man/enw_add_metaobs_features.Rd @@ -6,7 +6,7 @@ \usage{ enw_add_metaobs_features( metaobs, - holidays = c(), + holidays = NULL, holidays_to = "Sunday", datecol = "date" ) diff --git a/man/enw_assign_group.Rd b/man/enw_assign_group.Rd index fa963c47c..7dc1e38b1 100644 --- a/man/enw_assign_group.Rd +++ b/man/enw_assign_group.Rd @@ -4,7 +4,7 @@ \alias{enw_assign_group} \title{Assign a group to each row of a data.table} \usage{ -enw_assign_group(obs, by = c()) +enw_assign_group(obs, by = NULL) } \arguments{ \item{obs}{A \code{data.table} or \code{data.frame} without a \code{.group} column.} diff --git a/man/enw_complete_dates.Rd b/man/enw_complete_dates.Rd index c82e805ce..3a5a408c6 100644 --- a/man/enw_complete_dates.Rd +++ b/man/enw_complete_dates.Rd @@ -4,7 +4,7 @@ \alias{enw_complete_dates} \title{Complete missing reference and report dates} \usage{ -enw_complete_dates(obs, by = c(), max_delay, missing_reference = TRUE) +enw_complete_dates(obs, by = NULL, max_delay, missing_reference = TRUE) } \arguments{ \item{obs}{A \code{data.frame} containing at least the following variables: diff --git a/man/enw_cumulative_to_incidence.Rd b/man/enw_cumulative_to_incidence.Rd index 141d4ab20..f84bad0f7 100644 --- a/man/enw_cumulative_to_incidence.Rd +++ b/man/enw_cumulative_to_incidence.Rd @@ -4,7 +4,7 @@ \alias{enw_cumulative_to_incidence} \title{Calculate incidence of new reports from cumulative reports} \usage{ -enw_cumulative_to_incidence(obs, set_negatives_to_zero = TRUE, by = c()) +enw_cumulative_to_incidence(obs, set_negatives_to_zero = TRUE, by = NULL) } \arguments{ \item{obs}{A \code{data.frame} containing at least the following variables: diff --git a/man/enw_delay_filter.Rd b/man/enw_delay_filter.Rd index 3f1238bd0..da409bb89 100644 --- a/man/enw_delay_filter.Rd +++ b/man/enw_delay_filter.Rd @@ -19,8 +19,8 @@ that this is zero indexed and so includes the reference date and \code{max_delay - 1} other days.} } \value{ -A \code{data.frame} filtered so that dates by report are less than or equal -the reference date plus the maximum delay. +A \code{data.frame} filtered so that dates by report are less than or +equal the reference date plus the maximum delay. } \description{ Filter observations to restrict the maximum reporting delay diff --git a/man/enw_expectation.Rd b/man/enw_expectation.Rd index c30c2ff54..b6d2e0d22 100644 --- a/man/enw_expectation.Rd +++ b/man/enw_expectation.Rd @@ -6,9 +6,9 @@ \usage{ enw_expectation( r = ~0 + (1 | day:.group), - generation_time = c(1), + generation_time = 1, observation = ~1, - latent_reporting_delay = c(1), + latent_reporting_delay = 1, data, ... ) diff --git a/man/enw_incidence_to_cumulative.Rd b/man/enw_incidence_to_cumulative.Rd index 4d7c93cdd..39156065c 100644 --- a/man/enw_incidence_to_cumulative.Rd +++ b/man/enw_incidence_to_cumulative.Rd @@ -4,7 +4,7 @@ \alias{enw_incidence_to_cumulative} \title{Calculate cumulative reported cases from incidence of new reports} \usage{ -enw_incidence_to_cumulative(obs, by = c()) +enw_incidence_to_cumulative(obs, by = NULL) } \arguments{ \item{obs}{A \code{data.frame} containing at least the following variables: diff --git a/man/enw_manual_formula.Rd b/man/enw_manual_formula.Rd index 88d5d21cd..9c90dd797 100644 --- a/man/enw_manual_formula.Rd +++ b/man/enw_manual_formula.Rd @@ -6,9 +6,9 @@ \usage{ enw_manual_formula( data, - fixed = c(), - random = c(), - custom_random = c(), + fixed = NULL, + random = NULL, + custom_random = NULL, no_contrasts = FALSE, add_intercept = TRUE ) diff --git a/man/enw_metadata.Rd b/man/enw_metadata.Rd index 5915b73bf..e63cb928f 100644 --- a/man/enw_metadata.Rd +++ b/man/enw_metadata.Rd @@ -7,9 +7,9 @@ enw_metadata(obs, target_date = c("reference_date", "report_date")) } \arguments{ -\item{obs}{A \code{data.frame} or \code{data.table} with columns: \code{reference_date} and/or -\code{report_date}; at least one must be provided, \code{.group}, a grouping column -and a \code{date}, a \link{Date} column.} +\item{obs}{A \code{data.frame} or \code{data.table} with columns: \code{reference_date} +and/or \code{report_date}; at least one must be provided, \code{.group}, a grouping +column and a \code{date}, a \link{Date} column.} \item{target_date}{A character string, either "reference_date" or "report_date". The column corresponding to this string will be used diff --git a/man/enw_preprocess_data.Rd b/man/enw_preprocess_data.Rd index 5ef7e3423..0696c5efc 100644 --- a/man/enw_preprocess_data.Rd +++ b/man/enw_preprocess_data.Rd @@ -6,7 +6,7 @@ \usage{ enw_preprocess_data( obs, - by = c(), + by = NULL, max_delay = 20, set_negatives_to_zero = TRUE, ... diff --git a/man/enw_reps_with_complete_refs.Rd b/man/enw_reps_with_complete_refs.Rd index 500aa8342..42e056e78 100644 --- a/man/enw_reps_with_complete_refs.Rd +++ b/man/enw_reps_with_complete_refs.Rd @@ -5,7 +5,7 @@ \title{Identify report dates with complete (i.e up to the maximum delay) reference dates} \usage{ -enw_reps_with_complete_refs(new_confirm, max_delay, by = c()) +enw_reps_with_complete_refs(new_confirm, max_delay, by = NULL) } \arguments{ \item{new_confirm}{\code{new_confirm} \code{data.frame} output from diff --git a/man/enw_simulate_missing_reference.Rd b/man/enw_simulate_missing_reference.Rd index aa2e9fe95..22184d515 100644 --- a/man/enw_simulate_missing_reference.Rd +++ b/man/enw_simulate_missing_reference.Rd @@ -4,7 +4,7 @@ \alias{enw_simulate_missing_reference} \title{Simulate observations with a missing reference date.} \usage{ -enw_simulate_missing_reference(obs, proportion = 0.2, by = c()) +enw_simulate_missing_reference(obs, proportion = 0.2, by = NULL) } \arguments{ \item{obs}{A \code{data.frame} containing at least the following variables: diff --git a/man/epinowcast.Rd b/man/epinowcast.Rd index 56ff3024e..ffb407767 100644 --- a/man/epinowcast.Rd +++ b/man/epinowcast.Rd @@ -10,7 +10,7 @@ epinowcast( non_parametric = ~0, data = data), report = epinowcast::enw_report(non_parametric = ~0, structural = ~0, data = data), expectation = epinowcast::enw_expectation(r = ~0 + (1 | day:.group), generation_time = - c(1), observation = ~1, latent_reporting_delay = c(1), data = data), + 1, observation = ~1, latent_reporting_delay = 1, data = data), missing = epinowcast::enw_missing(formula = ~0, data = data), obs = epinowcast::enw_obs(family = "negbin", data = data), fit = epinowcast::enw_fit_opts(sampler = epinowcast::enw_sample, nowcast = TRUE, pp = diff --git a/vignettes/precompile.R b/vignettes/precompile.R index 91a9dd9af..b14775cf0 100644 --- a/vignettes/precompile.R +++ b/vignettes/precompile.R @@ -1,6 +1,6 @@ # Precompiled vignettes with long run times library(knitr) knit( - "vignettes/germany-age-stratified-nowcasting.Rmd.orig", - "vignettes/germany-age-stratified-nowcasting.Rmd" + file.path("vignettes", "germany-age-stratified-nowcasting.Rmd.orig"), + file.path("vignettes", "germany-age-stratified-nowcasting.Rmd") )