Skip to content

Commit 0d6cb23

Browse files
committed
Merge branch 'master' into suggests
2 parents d35ad29 + c63a777 commit 0d6cb23

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+379
-297
lines changed

DESCRIPTION

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: shinyscholar
2-
Version: 0.4.1
2+
Version: 0.4.2
33
Title: A Template for Creating Reproducible 'shiny' Applications
44
Description: Create a skeleton 'shiny' application with create_template() that is
55
reproducible, can be saved and meets academic standards for attribution.
@@ -35,7 +35,7 @@ Authors@R:
3535
person("Bruno", "Vilela", email = "bvilela@wustl.edu", role = "ctb"),
3636
person("Robert", "Muscarella", email = "bob.muscarella@gmail.com", role = "ctb"))
3737
Depends:
38-
R (>= 3.5.0),
38+
R (>= 4.1.0),
3939
bslib,
4040
gargoyle,
4141
leaflet (>= 2.0.2),
@@ -45,7 +45,6 @@ Imports:
4545
devtools,
4646
glue,
4747
knitr,
48-
magrittr,
4948
tools,
5049
zip,
5150
DT (>= 0.5),

NAMESPACE

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,3 @@ import(bslib)
2828
import(gargoyle)
2929
import(leaflet)
3030
import(shiny)
31-
importFrom(magrittr,"%>%")

NEWS.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,18 @@ shinyscholar 0.4.0
104104
- Fixed API calls in `select_query()` and `select_async()`
105105

106106
### Changes
107-
- Stopped running {shinytest2} tests on CRAN
108-
- Migrated from {promises} to {mirai} for running async tasks
109-
- Migrated to {bslib} layout functions and various UI tweaks
107+
- Stopped running `{shinytest2}` tests on CRAN
108+
- Migrated from `{promises}` to `{mirai}` for running async tasks
109+
- Migrated to `{bslib}` layout functions and various UI tweaks
110110
- Added a small footer linking to the CRAN package to generated apps
111111

112112
shinyscholar 0.4.1
113113
=============
114114
- Fix half-baked bslib migration
115115
- Further UI tweaks
116116

117-
117+
shinyscholar 0.4.2
118+
=============
119+
- Various tweaks to ensure that created apps pass `R CMD check`
120+
- Removed `{magrittr}` dependency and migrated to native pipes, increasing R dependency to v4.1.0
121+
- `create_module()` now creates skeleton functions that include `{roxygen2}` tags

R/create_template.R

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -85,62 +85,62 @@ create_template <- function(path, name, common_objects, modules, author,
8585
# Check inputs ====
8686

8787
if (!is.character(path)){
88-
logger %>% writeLog(type = "error", "path must be a character string")
88+
logger |> writeLog(type = "error", "path must be a character string")
8989
return()
9090
}
9191

9292
if (!dir.exists(path)){
93-
logger %>% writeLog(type = "error", "The specified path does not exist")
93+
logger |> writeLog(type = "error", "The specified path does not exist")
9494
return()
9595
}
9696

9797
if (!is.character(name)){
98-
logger %>% writeLog(type = "error", "name must be a character string")
98+
logger |> writeLog(type = "error", "name must be a character string")
9999
return()
100100
}
101101

102102
if (grepl("^[A-Za-z0-9]+$", name, perl = TRUE) == FALSE){
103-
logger %>% writeLog(type = "error", "Package names can only contain letters and numbers")
103+
logger |> writeLog(type = "error", "Package names can only contain letters and numbers")
104104
return()
105105
}
106106

107107
if (grepl("^[0-9]+$", substr(name, 1, 1), perl = TRUE) == TRUE){
108-
logger %>% writeLog(type = "error", "Package names cannot start with numbers")
108+
logger |> writeLog(type = "error", "Package names cannot start with numbers")
109109
return()
110110
}
111111

112112
online <- curl::has_internet()
113113

114114
if (online) {
115115
if (name %in% tools::CRAN_package_db()[, c("Package")]) {
116-
logger %>% writeLog(type = "error", "A package on CRAN already uses that name")
116+
logger |> writeLog(type = "error", "A package on CRAN already uses that name")
117117
return()
118118
}
119119
} else {
120-
logger %>% writeLog(type = "warning", "You are not online so your package name could
120+
logger |> writeLog(type = "warning", "You are not online so your package name could
121121
not be checked against existing CRAN packages")
122122
}
123123

124124
if (dir.exists(file.path(path, name))){
125-
logger %>% writeLog(type = "error", "The specified app directory already exists")
125+
logger |> writeLog(type = "error", "The specified app directory already exists")
126126
return()
127127
}
128128

129129
if (!is.vector(common_objects) || !is.character(common_objects)){
130-
logger %>% writeLog(type = "error", "common_objects must be a vector of character strings")
130+
logger |> writeLog(type = "error", "common_objects must be a vector of character strings")
131131
return()
132132
}
133133

134134
if (any(common_objects %in% c("meta", "logger", "state", "poly", "tasks"))){
135135
conflicts <- common_objects[common_objects %in% c("meta", "logger", "state", "poly", "tasks", "reset")]
136136
conflicts <- paste(conflicts, collapse = ",")
137-
logger %>% writeLog(type = "error", glue::glue("common_objects contains {conflicts} which are included
137+
logger |> writeLog(type = "error", glue::glue("common_objects contains {conflicts} which are included
138138
in common by default. Please choose a different name."))
139139
return()
140140
}
141141

142142
if (!is.data.frame(modules)){
143-
logger %>% writeLog(type = "error", "modules must be a dataframe")
143+
logger |> writeLog(type = "error", "modules must be a dataframe")
144144
return()
145145
}
146146

@@ -150,33 +150,33 @@ create_template <- function(path, name, common_objects, modules, author,
150150
missing_column <- module_columns[!(module_columns %in% colnames(modules))]
151151
missing_column <- paste(missing_column, collapse = ",")
152152
if (missing_column == "async"){
153-
logger %>% writeLog(type = "warning", glue::glue("As of v0.2.0 the modules dataframe should also contain an async column"))
153+
logger |> writeLog(type = "warning", glue::glue("As of v0.2.0 the modules dataframe should also contain an async column"))
154154
modules <- cbind(modules, data.frame("async" = rep(FALSE, nrow(modules))))
155155
} else {
156-
logger %>% writeLog(type = "error", glue::glue("The modules dataframe must contain the column(s): {missing_column}"))
156+
logger |> writeLog(type = "error", glue::glue("The modules dataframe must contain the column(s): {missing_column}"))
157157
return()
158158
}
159159
}
160160

161161
if (!all(colnames(modules) %in% module_columns)){
162162
invalid_column <- colnames(modules)[!colnames(modules) %in% module_columns]
163163
invalid_column <- paste(invalid_column, collapse = ",")
164-
logger %>% writeLog(type = "error", glue::glue("The modules dataframe contains {invalid_column} which is/are not valid column names"))
164+
logger |> writeLog(type = "error", glue::glue("The modules dataframe contains {invalid_column} which is/are not valid column names"))
165165
return()
166166
}
167167

168168
if (any(modules$map) == TRUE && include_map == FALSE){
169-
logger %>% writeLog(type = "info", "Your modules use a map but you had not included it so changing include_map to TRUE")
169+
logger |> writeLog(type = "info", "Your modules use a map but you had not included it so changing include_map to TRUE")
170170
include_map <- TRUE
171171
}
172172

173173
if (any(modules$map) == FALSE && include_map == TRUE){
174-
logger %>% writeLog(type = "error", "You have included a map but none of your modules use it")
174+
logger |> writeLog(type = "error", "You have included a map but none of your modules use it")
175175
return()
176176
}
177177

178178
if (any(modules$result) == FALSE){
179-
logger %>% writeLog(type = "error", "At least one module must return results")
179+
logger |> writeLog(type = "error", "At least one module must return results")
180180
return()
181181
}
182182

@@ -187,12 +187,12 @@ create_template <- function(path, name, common_objects, modules, author,
187187
}
188188

189189
if (!is.character(author)){
190-
logger %>% writeLog(type = "error", "author must be a character string")
190+
logger |> writeLog(type = "error", "author must be a character string")
191191
return()
192192
}
193193

194194
if (!is.logical(c(include_map, include_table, include_code, install))){
195-
logger %>% writeLog(type = "error", "include_map, include_table,
195+
logger |> writeLog(type = "error", "include_map, include_table,
196196
include_code & install must be TRUE or FALSE")
197197
return()
198198
}
@@ -216,8 +216,7 @@ create_template <- function(path, name, common_objects, modules, author,
216216

217217
if (async){
218218
import_line <- grep("*Imports*", description_lines)
219-
description_lines <- append(description_lines, " bslib,", import_line)
220-
description_lines <- append(description_lines, " mirai,", import_line + 7)
219+
description_lines <- append(description_lines, " mirai,", import_line + 6)
221220
}
222221

223222
if (include_map){
@@ -509,7 +508,9 @@ create_template <- function(path, name, common_objects, modules, author,
509508

510509
helper_function_params <- c(
511510
file = system.file("app_skeleton", "helper_functions.Rmd", package = "shinyscholar"),
512-
list(include_map = include_map)
511+
list(include_code = include_code,
512+
include_map = include_map,
513+
async = async)
513514
)
514515
helper_function_lines <- tidy_purl(helper_function_params)
515516
writeLines(helper_function_lines, file.path(path, "R", "helper_functions.R"))
@@ -527,7 +528,8 @@ create_template <- function(path, name, common_objects, modules, author,
527528

528529
# Install package ====
529530
if (install){
530-
devtools::install_local(path = path, force = TRUE)
531+
devtools::document(path)
532+
devtools::install(path, force = TRUE)
531533
}
532534

533535
invisible()

R/custom_modules.R

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,14 @@ create_module <- function(id, dir, map = FALSE, result = FALSE, rmd = FALSE, sav
9797
writeLines(module_lines, file.path(module_dir, glue::glue("{id}.R")))
9898

9999
# create empty function
100-
empty_function <- paste0(id," <- function(x){return(NULL)}")
101-
writeLines(empty_function, file.path(dir, "R", paste0(id, "_f.R")))
100+
function_params <- c(
101+
file = system.file("module_skeleton", "function.Rmd", package = "shinyscholar"),
102+
list(id = id,
103+
async = async)
104+
)
105+
106+
function_lines <- tidy_purl(function_params)
107+
writeLines(function_lines, file.path(dir, "R", paste0(id, "_f.R")))
102108

103109
# create test
104110
desc <- readLines(file.path(dir, "DESCRIPTION"))

R/helper_functions.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ printVecAsis <- function(x) {
2424
check_url <- function(url){
2525
req <- httr2::request(url)
2626
resp <- tryCatch(
27-
req %>% httr2::req_perform(),
27+
req |> httr2::req_perform(),
2828
httr2_http_404 = function(cnd){NULL},
2929
httr2_failure = function(cnd){NULL},
3030
httr2_error = function(cnd){NULL}

R/plot_hist_f.R

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,52 @@
33
#' and extracts values from a raster image, returning a histogram of density
44
#' @param raster SpatRaster object
55
#' @param bins The number of breaks in the histogram
6+
#' @param palette character. The colour palette to use
7+
#' @param name character. The name of the variable
68
#' @param logger Stores all notification messages to be displayed in the Log
79
#' Window. Insert the logger reactive list here for running in
810
#' shiny, otherwise leave the default NULL
9-
#' @return a list of class histogram
11+
#' @return a function that generates a histogram
1012
#' @author Simon Smart <simon.smart@@cantab.net>
1113
#' @examples
1214
#' if (check_suggests(example = TRUE)) {
1315
#' raster <- terra::rast(ncol = 8, nrow = 8)
1416
#' raster[] <- sapply(1:terra::ncell(raster), function(x){
1517
#' rnorm(1, ifelse(x %% 8 != 0, x %% 8, 8), 3)})
16-
#' histogram <- plot_hist(raster, bins = 10)
18+
#' histogram <- plot_hist(raster, bins = 10, palette = "Greens", name = "Example")
19+
#' histogram()
1720
#' } else {
1821
#' message('reinstall with install.packages("shinyscholar", dependencies = TRUE)
1922
#' to run this example')
2023
#' }
2124
#' @export
2225

23-
plot_hist <- function(raster, bins, logger = NULL) {
26+
plot_hist <- function(raster, bins, palette, name, logger = NULL) {
2427

2528
check_suggests()
2629

27-
if (!("SpatRaster" %in% class(raster))){
28-
logger %>% writeLog(type = "error", "The raster must be a SpatRaster")
30+
if (!inherits(raster, "SpatRaster")){
31+
logger |> writeLog(type = "error", "The raster must be a SpatRaster")
2932
return()
3033
}
3134

3235
if (!is.numeric(bins)){
33-
logger %>% writeLog(type = "error", "bins must be numeric")
36+
logger |> writeLog(type = "error", "bins must be numeric")
37+
return()
38+
}
39+
40+
if (!inherits(palette, "character")){
41+
logger |> writeLog(type = "error", "palette must be a character string")
42+
return()
43+
}
44+
45+
if (!inherits(name, "character")){
46+
logger |> writeLog(type = "error", "name must be a character string")
47+
return()
48+
}
49+
50+
if (!(palette %in% c("Greens", "YlOrRd", "Greys", "Blues"))){
51+
logger |> writeLog(type = "error", "palette must be either 'Greens', 'YlOrRd', 'Greys' or 'Blues'")
3452
return()
3553
}
3654

@@ -40,5 +58,11 @@ plot_hist <- function(raster, bins, logger = NULL) {
4058
max(raster_values, na.rm = TRUE),
4159
length.out = bins + 1))
4260
histogram$density <- histogram$counts / sum(histogram$counts) * 100
43-
histogram
61+
62+
pal <- RColorBrewer::brewer.pal(9, palette)
63+
pal_ramp <- grDevices::colorRampPalette(c(pal[1], pal[9]))
64+
hist_cols <- pal_ramp(bins)
65+
66+
function(){plot(histogram, freq = F, main = "", xlab = name, ylab = "Frequency (%)", col = hist_cols)}
67+
4468
}

R/plot_scatter_f.R

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,60 @@
55
#' @param raster SpatRaster. Raster to be sampled
66
#' @param sample numeric. Number of points to sample
77
#' @param axis character. Which axis coordinates of the raster to return
8+
#' @param name character. The name of the raster variable
89
#' @param logger Stores all notification messages to be displayed in the Log
910
#' Window. Insert the logger reactive list here for running in
1011
#' shiny, otherwise leave the default NULL
11-
#' @return a dataframe containing the axis values and the cell values
12+
#' @return a function that generates a scatterplot
1213
#' @author Simon Smart <simon.smart@@cantab.net>
1314
#' @examples
1415
#' if (check_suggests(example = TRUE)) {
1516
#' raster <- terra::rast(ncol = 8, nrow = 8)
1617
#' raster[] <- sapply(1:terra::ncell(raster), function(x){
1718
#' rnorm(1, ifelse(x %% 8 != 0, x %% 8, 8), 3)})
18-
#' scatterplot <- plot_scatter(raster, sample = 10, axis = "y")
19+
#' scatterplot <- plot_scatter(raster, sample = 10, axis = "Longitude", name = "Example")
20+
#' scatterplot()
1921
#' } else {
2022
#' message('reinstall with install.packages("shinyscholar", dependencies = TRUE)
2123
#' to run this example')
2224
#' }
2325
#' @export
24-
plot_scatter <- function(raster, sample, axis, logger = NULL) {
26+
plot_scatter <- function(raster, sample, axis, name, logger = NULL) {
2527

2628
check_suggests()
2729

28-
if (!("SpatRaster" %in% class(raster))){
29-
logger %>% writeLog(type = "error", "The raster must be a SpatRaster")
30+
if (!inherits(raster, "SpatRaster")){
31+
logger |> writeLog(type = "error", "The raster must be a SpatRaster")
3032
return()
3133
}
3234

3335
if (!is.numeric(sample)){
34-
logger %>% writeLog(type = "error", "sample must be numeric")
36+
logger |> writeLog(type = "error", "sample must be numeric")
3537
return()
3638
}
3739

38-
if (!(axis %in% c("x", "y"))){
39-
logger %>% writeLog(type = "error", "axis must be either x or y")
40+
if (!inherits(axis, "character")){
41+
logger |> writeLog(type = "error", "axis must be a character string")
4042
return()
4143
}
4244

43-
samp <- terra::spatSample(raster, sample, method = "random", xy = TRUE, as.df = TRUE)
44-
colnames(samp)[3] <- "value"
45-
samp[, c(axis, "value")]
45+
if (!(axis %in% c("Longitude", "Latitude"))){
46+
logger |> writeLog(type = "error", "axis must be either Latitude or Longitude")
47+
return()
48+
}
49+
50+
if (!inherits(name, "character")){
51+
logger |> writeLog(type = "error", "name must be a character string")
52+
return()
53+
}
54+
55+
if (axis == "Longitude"){short_axis <- "x"} else {short_axis <- "y"}
56+
57+
sampled <- terra::spatSample(raster, sample, method = "random", xy = TRUE, as.df = TRUE)
58+
colnames(sampled)[3] <- "value"
59+
sampled <-sampled[, c(short_axis, "value")]
60+
61+
function(){plot(sampled[[1]], sampled[[2]], xlab = axis, ylab = name)}
62+
4663

4764
}

0 commit comments

Comments
 (0)