├── .Rbuildignore ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── class-projects_author.R ├── class-projects_stage.R ├── edit.R ├── email_authors.R ├── file_management.R ├── getters.R ├── header.R ├── metadata_manipulation.R ├── new.R ├── projects.R ├── reproducibility.R ├── set_generics.R ├── setup.R ├── sysdata.rda ├── update.R ├── utilities.R ├── utils-pipe.R ├── validation.R └── zzz.R ├── README.Rmd ├── README.md ├── cran-comments.md ├── demonstration ├── .Renviron ├── demonstration.md └── projects │ ├── .metadata │ ├── affiliations.rds │ ├── author_affiliation_assoc.rds │ ├── authors.rds │ ├── project_author_assoc.rds │ └── projects.rds │ ├── .templates │ ├── CONSORT_protocol.Rmd │ ├── STROBE_protocol.Rmd │ └── default_folder │ │ ├── pXXXX.Rproj │ │ └── progs │ │ ├── 01_protocol.Rmd │ │ ├── 02_datawork.Rmd │ │ ├── 03_analysis.Rmd │ │ ├── 04_report.Rmd │ │ ├── citations.bib │ │ ├── style.css │ │ └── styles.docx │ └── p0012 │ ├── data │ ├── 02_datawork_objects.RData │ └── 03_analysis_objects.RData │ ├── data_raw │ ├── toy-dataset.zip │ └── toy_dataset.csv │ ├── figures │ └── income_by_gender_plot.png │ ├── p0012.Rproj │ └── progs │ ├── 01_protocol.Rmd │ ├── 01_protocol.docx │ ├── 02_datawork.Rmd │ ├── 02_datawork.html │ ├── 03_analysis.Rmd │ ├── 03_analysis.html │ ├── 04_report.Rmd │ ├── 04_report.html │ ├── citations.bib │ ├── session_info │ ├── analysis │ │ └── session_info_20190903_15꞉42꞉18_EDT.txt │ ├── datawork │ │ └── session_info_20190903_15꞉41꞉21_EDT.txt │ ├── protocol │ │ └── session_info_20190903_15꞉40꞉10_EDT.txt │ └── report │ │ └── session_info_20190903_15꞉43꞉17_EDT.txt │ ├── style.css │ └── styles.docx ├── inst ├── extdata │ └── ptype_data_creator.Rmd └── templates │ ├── 02_datawork.Rmd │ ├── 03_analysis.Rmd │ ├── 04_report.Rmd │ ├── CONSORT_protocol.Rmd │ ├── STROBE_protocol.Rmd │ ├── citations.bib │ ├── pXXXX.Rproj │ ├── style.css │ └── styles.docx ├── man ├── README │ ├── README-workflow.png │ └── citations.bib ├── display_metadata.Rd ├── email_authors.Rd ├── export_project.Rd ├── file_management.Rd ├── header.Rd ├── new_edit_delete.Rd ├── pipe.Rd ├── projects-package.Rd ├── projects_author-vctrs.Rd ├── projects_author.Rd ├── projects_folder.Rd ├── projects_stage-vctrs.Rd ├── projects_stage.Rd ├── reordering.Rd ├── save_session_info.Rd ├── setup_projects.Rd └── update_metadata.Rd └── tests ├── testthat.R └── testthat └── test-setup.R /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^CRAN-RELEASE$ 2 | ^LICENSE\.md$ 3 | ^projects\.Rproj$ 4 | ^\.Rproj\.user$ 5 | ^manuscript$ 6 | ^development_code$ 7 | ^cran-comments\.md$ 8 | ^README\.Rmd$ 9 | ^README-.*\.png$ 10 | ^demonstration$ 11 | ^rmedicine2019\.pptx$ 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | projects.Rproj 3 | .Rhistory 4 | .RData 5 | manuscript 6 | development_code 7 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: projects 2 | Title: A Project Infrastructure for Researchers 3 | Version: 2.1.99.9990 4 | Authors@R: 5 | c(person(given = "Nik", 6 | family = "Krieger", 7 | role = c("aut", "cre"), 8 | email = "nk@case.edu"), 9 | person(given = "Adam", 10 | family = "Perzynski", 11 | role = "aut"), 12 | person(given = "Jarrod", 13 | family = "Dalton", 14 | role = "aut")) 15 | Description: Provides a project infrastructure with a focus on manuscript 16 | creation. Creates a project folder with a single command, containing 17 | subdirectories for specific components, templates for manuscripts, and 18 | so on. 19 | License: MIT + file LICENSE 20 | URL: https://cran.r-project.org/package=projects 21 | Depends: 22 | R (>= 3.4.0) 23 | Imports: 24 | dplyr (>= 0.7.0), 25 | fs (>= 1.4.1), 26 | lubridate, 27 | magrittr (>= 1.5), 28 | methods, 29 | purrr (>= 0.3.0), 30 | readr (>= 1.4.0), 31 | rlang (>= 0.4.6), 32 | rstudioapi, 33 | sessioninfo (>= 1.1.1), 34 | stringr (>= 1.4.0), 35 | vctrs (>= 0.2.4), 36 | zip (>= 2.0.4) 37 | Suggests: 38 | forcats, 39 | here, 40 | testthat, 41 | tibble 42 | Config/testthat/edition: 3 43 | Encoding: UTF-8 44 | RoxygenNote: 7.1.1 45 | Collate: 46 | 'set_generics.R' 47 | 'class-projects_author.R' 48 | 'class-projects_stage.R' 49 | 'new.R' 50 | 'edit.R' 51 | 'email_authors.R' 52 | 'file_management.R' 53 | 'getters.R' 54 | 'header.R' 55 | 'metadata_manipulation.R' 56 | 'projects.R' 57 | 'reproducibility.R' 58 | 'setup.R' 59 | 'update.R' 60 | 'utilities.R' 61 | 'utils-pipe.R' 62 | 'validation.R' 63 | 'zzz.R' 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2018 2 | COPYRIGHT HOLDER: Nik Krieger and Jarrod Dalton 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2018 Nik Krieger and Jarrod Dalton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | # Acknowledgements 24 | 25 | Acknowledgements: The authors of this package acknowledge the support provided by members of the Northeast Ohio Cohort for Atherosclerotic Risk Estimation (NEOCARE) investigative team: Claudia Coulton, Douglas Gunzler, Darcy Freedman, Neal Dawson, Michael Rothberg, David Zidar, David Kaelber, Douglas Einstadter, Alex Milinovich, Monica Webb Hooper, Kristen Hassmiller-Lich, Ye Tian (Devin), Kristen Berg, and Sandy Andrukat. 26 | 27 | # Funding comment 28 | 29 | This work was supported by The National Institute on Aging of the National Institutes of Health under award number R01AG055480. The content is solely the responsibility of the authors and does not necessarily represent the official views of the National Institutes of Health. 30 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(Ops,projects_author) 4 | S3method(Ops,projects_stage) 5 | S3method(print,projects_metadata_tbl) 6 | S3method(vec_cast,projects_author) 7 | S3method(vec_cast,projects_stage) 8 | S3method(vec_cast.character,projects_author) 9 | S3method(vec_cast.character,projects_stage) 10 | S3method(vec_cast.double,projects_author) 11 | S3method(vec_cast.double,projects_stage) 12 | S3method(vec_cast.integer,projects_author) 13 | S3method(vec_cast.integer,projects_stage) 14 | S3method(vec_cast.projects_author,character) 15 | S3method(vec_cast.projects_author,default) 16 | S3method(vec_cast.projects_author,integer) 17 | S3method(vec_cast.projects_author,projects_author) 18 | S3method(vec_cast.projects_stage,character) 19 | S3method(vec_cast.projects_stage,default) 20 | S3method(vec_cast.projects_stage,double) 21 | S3method(vec_cast.projects_stage,integer) 22 | S3method(vec_cast.projects_stage,projects_stage) 23 | S3method(vec_ptype2,projects_author) 24 | S3method(vec_ptype2,projects_stage) 25 | S3method(vec_ptype2.character,projects_author) 26 | S3method(vec_ptype2.character,projects_stage) 27 | S3method(vec_ptype2.projects_author,character) 28 | S3method(vec_ptype2.projects_author,default) 29 | S3method(vec_ptype2.projects_author,projects_author) 30 | S3method(vec_ptype2.projects_stage,character) 31 | S3method(vec_ptype2.projects_stage,default) 32 | S3method(vec_ptype2.projects_stage,projects_stage) 33 | S3method(vec_ptype_abbr,projects_author) 34 | S3method(vec_ptype_abbr,projects_stage) 35 | export("%>%") 36 | export("%in%") 37 | export("%in%.projects_author") 38 | export("%in%.projects_stage") 39 | export(affiliations) 40 | export(archive_project) 41 | export(authors) 42 | export(copy_project) 43 | export(delete_affiliation) 44 | export(delete_author) 45 | export(delete_project) 46 | export(delete_task) 47 | export(edit_affiliation) 48 | export(edit_author) 49 | export(edit_project) 50 | export(edit_task) 51 | export(email_authors) 52 | export(export_project) 53 | export(finish) 54 | export(header) 55 | export(ideas) 56 | export(is_projects_author) 57 | export(manuscripts) 58 | export(match) 59 | export(match.projects_author) 60 | export(match.projects_stage) 61 | export(move_project) 62 | export(move_projects_folder) 63 | export(new_affiliation) 64 | export(new_author) 65 | export(new_idea) 66 | export(new_project) 67 | export(new_project_group) 68 | export(new_task) 69 | export(open_project) 70 | export(projects) 71 | export(projects_author) 72 | export(projects_folder) 73 | export(projects_stage) 74 | export(rename_folder) 75 | export(rename_projects_folder) 76 | export(reorder_affiliations) 77 | export(reorder_authors) 78 | export(save_session_info) 79 | export(setup_projects) 80 | export(tasks) 81 | export(update_metadata) 82 | export(vec_cast.projects_author) 83 | export(vec_cast.projects_stage) 84 | export(vec_ptype2.projects_author) 85 | export(vec_ptype2.projects_stage) 86 | exportClasses(projects_author) 87 | exportClasses(projects_stage) 88 | exportMethods("%in%") 89 | exportMethods(match) 90 | import(vctrs) 91 | importFrom(magrittr,"%>%") 92 | importFrom(rlang,.data) 93 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | 2 | # projects 2.1.99.9990 3 | 4 | ## Major update: 5 | 6 | - Addition of tasks, which involves the new functions `tasks()`, `new_task()`, `edit_task()`, `delete_task()`, and `finish()`. This adds another metadata table (tasks.rds) to the little relational database that projects maintains. 7 | 8 | ## Minor update: 9 | 10 | - A `vctrs` `.ptype` has been added to the internal name space of the package. The metadata tables are `vctrs::vec_cast()` to these `.ptype`s every time they are re-saved. 11 | - Code updates. 12 | - Updated documentation. 13 | 14 | # projects 2.1.3 15 | 16 | ## Minor updates: 17 | - Removed names from arguments passed to `readr::write_lines()` and `readr::write_rds()` since they have deprecated `path` in favor of `file`. 18 | - Combined the `setup` and `load_libraries` code chunks in all applicable template .Rmd files. 19 | - Removed `LazyData` line from `DESCRIPTION` file in compliance with new CRAN check. 20 | 21 | # projects 2.1.2 22 | 23 | ## Minor updates: 24 | - Bug fix to `projects()`'s handling of the `path` argument, accommodating latest behavior of `fs::path_abs()`. 25 | 26 | # projects 2.1.1 27 | 28 | ## Minor updates: 29 | - Bug fix after breaking change in vctrs (`vec_cast(x, to = character())` changed to `as.character(x)`) 30 | 31 | # projects 2.1.0 32 | 33 | ## Major updates: 34 | - Addition of `rename_projects_folder()` and `move_projects_folder()` 35 | - Addition of `path` argument to `projects()`, allowing users to filter by subdirectory 36 | - Incorporation of `vctrs` package for `projects_stage` and `projects_author` classes 37 | 38 | ## Minor updates: 39 | - `projects()` now prints a maximum of 100 rows by default. 40 | - `open_project()` attempts to locate projects on shared servers when the local `projects_folder()` value differs from the server's `projects_folder()` value 41 | - Backslash inserted before any single quotation marks in projects folder path before being written to .Renviron 42 | - Bug, documentation, README improvements 43 | 44 | # projects 2.0.0 45 | 46 | ## Major updates: 47 | - `new_project()` now copies a single template project folder within *.templates* instead of assembling multiple template components into a file. This allows users to customize project folders to a very high degree. Thus, `new_project()` has fewer arguments, having only `template_folder` insofar as template-related arguments. 48 | - Consequently, header/title page YAML text is NOT written automatically into .Rmd files when they are created by `new_project()`. Users must run `header()` and copy the resulting text into desired *.Rmd* files. 49 | - Added the function email_authors(), which opens a new email for the currently open project (or, a specified project). 50 | 51 | ## Minor updates: 52 | - There are now separate arguments in `new_project()` and `copy_project()` for specifying the new project's folder name. It can be distinct from a project's `short_title` and its `id` number. 53 | - Updated documentation, 54 | - Tilde expansion is performed in `setup_projects()` 55 | - Added tests 56 | 57 | # projects 1.3.0 58 | 59 | ## Major updates 60 | - `save_session_info()` function for saving `sessioninfo::session_info()` to a text file. 61 | - `export_project()` for zipping project folders 62 | 63 | ## Minor updates 64 | - Improvements to default .Rmd files. 65 | - Code improvements 66 | 67 | # projects 1.2.0.9000 68 | 69 | ## Major updates 70 | - Moved all header material to YAML when generating 01_protocol.Rmd and 04_report.Rmd. 71 | - YAML Output options no longer written in function; rather, they are expected to already be in the templates. 72 | - Addition of .docx style template. 73 | 74 | ## Minor updates 75 | - Other minor tweaks to default .Rmd files. 76 | 77 | # projects 1.1.4.9000 78 | 79 | ## Major updates 80 | - Bug fix: exported all methods for the `projects_stage` and `projects_author` S3 classes so that the class would not be stripped. 81 | 82 | ## Minor updates 83 | - Made `reorder_authors()` and all `edit_*()` functions to stop printing metadata after successful editing. 84 | - Removed the `reprint_header` argument from `reorder_authors()` function, but added a message beckoning user to run `header()`, as in `edit_project()`. 85 | 86 | # projects 1.1.3.9000 87 | 88 | ## Minor updates: 89 | - Changed printing of projects table so it displays projects in descending order by stage before sorting them by id. 90 | 91 | 92 | # projects 1.1.2.9000 93 | 94 | ## Minor updates: 95 | - Required a later rlang version so that as_label() is available. 96 | 97 | 98 | # projects 1.1.1 99 | 100 | ## Major updates: 101 | - Fix of show-stopping bugs with update_metadata() and edit_project() 102 | 103 | 104 | # projects 1.1.0 105 | 106 | ## Minor updates: 107 | - Documentation updates for functions created in version 1.0.0 and 1.0.1. 108 | 109 | 110 | # projects 1.0.1.9000 111 | 112 | ## Major updates: 113 | - Fixed bug in internal acquisition of metadata tables. 114 | - Fixed bug in open_projects() 115 | 116 | ## Minor update: 117 | - Changed number of rows that projects(), authors(), and affiliations() tibbles will print 118 | 119 | 120 | 121 | # projects 1.0.0.9000 122 | 123 | ## Major update: 124 | - Created S3 classes implemented for each of stage and special authors (current_owner, corresp_auth, creator). 125 | - Added update_metadata() function to assist with updating metadata from projects version 0.X.X to 1.X.X 126 | - Addition of ideas(), new_idea(), and manuscripts(). 127 | - Overhaul of underlying code. 128 | 129 | ## Minor updates: 130 | - More customizable print options for projects(), 131 | - Minor improvements to printing of projects at the end of new_project() and edit_project() 132 | 133 | 134 | # projects 0.2.1.9000 135 | 136 | ## Major update: 137 | - Instances of fs::path_home() were changed to fs::path_home_r() so that .Renviron files would be put in the correct place (i.e., the directory that R considers to be the home directory, which is where R actually looks for .Renviron files). 138 | 139 | 140 | 141 | # projects 0.2.0.9000 142 | 143 | ## Major updates 144 | 145 | Users can now create custom names for project folders, linking the name to `short_title`: 146 | - Added the function `rename_folder()`, which enables the user to rename project folders. Added an example of this. 147 | - Added the logical argument `stitle_as_folder` to `new_project()`, which if `TRUE` makes the folder name of new projects the same as its `short_title`. 148 | - Added the argument `new_short_title` to `copy_project()`, which enables users to change the project copy's folder name and/or `short_title`. 149 | - Made the `path` argument in `copy_project()` second instead of fourth. 150 | 151 | ## Minor updates: 152 | - Made `open_project()` better handle instances of missing/multiple .Rproj files. 153 | - Documentation updates 154 | 155 | 156 | 157 | # projects 0.1.1.9000 158 | 159 | ## Minor updates: 160 | - Updated README.md so that it properly reflects how to install the `projects` package. 161 | - Updated README.md so that it contains CRAN version and download count badges. 162 | 163 | 164 | 165 | # projects 0.1.0 166 | 167 | ## Major updates: 168 | - Release. 169 | -------------------------------------------------------------------------------- /R/class-projects_author.R: -------------------------------------------------------------------------------- 1 | 2 | #' \code{projects_author} vector 3 | #' 4 | #' Objects of this class contain both the \code{id} and the \code{last_name} of 5 | #' an author so that the package and the user, respectively, can easily identify 6 | #' the author. 7 | #' 8 | #' Essentially, this is a character string of the form: 9 | #' 10 | #' \code{id: last_name} 11 | #' 12 | #' \code{projects_author()} coerces an integer or character vector to a 13 | #' \code{projects_author} object, validating each element against the existing 14 | #' \code{\link{authors}()} table. 15 | #' 16 | #' @section Numeric coercion methods: \code{\link{as.integer}()}, 17 | #' \code{\link{as.double}()}, and \code{\link{as.numeric}()} return the 18 | #' \code{id} portion of the \code{projects_author} object as an 19 | #' integer/double. The methods for the equality and value matching functions 20 | #' described below make use of these numeric coercion methods. Users desiring 21 | #' to apply value matching functions other than the ones described below may 22 | #' similarly take advantage of these. 23 | #' 24 | #' @section Equality and value matching methods: Methods for \code{\link{==}}, 25 | #' \code{\link{!=}}, \code{\link{match}()}, and \code{\link{\%in\%}} enable 26 | #' users to test equality and to value match among \code{projects_author} 27 | #' objects and as well as between \code{projects_author} objects and unclassed 28 | #' numbers/characters. When testing or matching against a numeric vector, the 29 | #' \code{projects_author} object is first coerced to an integer with the 30 | #' \code{as.integer()} method described above. When testing or matching 31 | #' against a character vector, the character vector is validated against the 32 | #' \code{\link{authors}()} table. 33 | #' 34 | #' @param x For \code{projects_author()}, an integer or character vector. For 35 | #' \code{is_projects_author()}, an object to test. 36 | #' 37 | #' For \code{\link{match}()} and \code{\link{\%in\%}}, an integer, a character 38 | #' string, or a \code{projects_author} object. See \code{\link{match}()} and 39 | #' \strong{Equality and value matching methods} below. 40 | #' 41 | #' @param table An integer number, a character string, or a 42 | #' \code{projects_author} object. See \code{\link{match}()} and 43 | #' \strong{Equality and value matching methods} below. 44 | #' 45 | #' @param nomatch See \code{\link{match}()}. 46 | #' 47 | #' @param incomparables An integer number, a character string, or a 48 | #' \code{projects_author} object. See \code{\link{match}()}. 49 | #' 50 | #' @seealso \code{\link{Ops}}; \code{\link[methods]{Methods_for_Nongenerics}}. 51 | #' 52 | #' @examples 53 | #' ############################################################################# 54 | #' # SETUP 55 | #' old_home <- Sys.getenv("HOME") 56 | #' old_ppath <- Sys.getenv("PROJECTS_FOLDER_PATH") 57 | #' temp_dir <- tempfile("dir") 58 | #' dir.create(temp_dir) 59 | #' Sys.unsetenv("PROJECTS_FOLDER_PATH") 60 | #' Sys.setenv(HOME = temp_dir) 61 | #' setup_projects(path = temp_dir) 62 | #' new_author("chuck", "jonesman", id = 33) 63 | #' new_author("Hattie", "Hatsman", id = 45) 64 | #' ############################################################################# 65 | #' 66 | #' jones <- projects_author("33: Jones") 67 | #' 68 | #' jones 69 | #' 70 | #' as.integer(jones) # 33 71 | #' 72 | #' jones == 33 # TRUE 73 | #' jones == 10 # FALSE 74 | #' jones != 33 # FALSE 75 | #' 76 | #' jones %in% c(20:40) # TRUE 77 | #' match(jones, c(31:40)) # 3 78 | #' 79 | #' # Comparing a projects_author object to a character vector results in the 80 | #' # character strings being validated against the authors() table. Then, the id 81 | #' # numbers are compared. 82 | #' jones == c("jOnES", "hat") # TRUE FALSE 83 | #' 84 | #' ############################################################################# 85 | #' # Cleanup (or just restart R) 86 | #' Sys.setenv(HOME = old_home, PROJECTS_FOLDER_PATH = old_ppath) 87 | #' @import vctrs 88 | #' @export 89 | projects_author <- function(x = character()) { 90 | x <- as.character(x) 91 | validate_projects_author(x) 92 | } 93 | 94 | 95 | #' @rdname projects_author 96 | #' @export 97 | is_projects_author <- function(x) { 98 | inherits(x, "projects_author") 99 | } 100 | 101 | 102 | new_projects_author <- function(x = character()) { 103 | vec_assert(x, character()) 104 | new_vctr(x, class = "projects_author") 105 | } 106 | 107 | 108 | #' @rdname projects_author 109 | #' @export 110 | methods::setClass("projects_author") 111 | 112 | #' @export 113 | vec_ptype_abbr.projects_author <- function(x, ...) "prjaut" 114 | 115 | validate_projects_author <- function(x, 116 | authors_table = authors_internal(p_path), 117 | p_path = get_p_path(), 118 | na.ok = TRUE) { 119 | x_valid <- 120 | validate_unique_entry( 121 | x = x, 122 | table = authors_table, 123 | what = "author", 124 | na.ok = na.ok, 125 | zero.ok = TRUE 126 | ) 127 | 128 | if (nrow(x_valid) == 0L) { 129 | new_projects_author(NA_character_) 130 | } else { 131 | new_projects_author(paste0(x_valid$id, ": ", x_valid$last_name)) 132 | } 133 | } 134 | 135 | 136 | 137 | 138 | #' @rdname projects_author-vctrs 139 | #' @method vec_ptype2 projects_author 140 | #' @export 141 | #' @export vec_ptype2.projects_author 142 | vec_ptype2.projects_author <- function(x, y, ...) 143 | UseMethod("vec_ptype2.projects_author", y) 144 | 145 | #' @method vec_ptype2.projects_author default 146 | #' @export 147 | vec_ptype2.projects_author.default <- function(x, y, ..., 148 | x_arg = "x", y_arg = "y") 149 | vec_default_ptype2(x, y, x_arg = x_arg, y_arg = y_arg) 150 | 151 | #' @method vec_ptype2.projects_author projects_author 152 | #' @export 153 | vec_ptype2.projects_author.projects_author <- function(x, y, ...) 154 | new_projects_author() 155 | 156 | #' @method vec_ptype2.projects_author character 157 | #' @export 158 | vec_ptype2.projects_author.character <- function(x, y, ...) character() 159 | 160 | #' @method vec_ptype2.character projects_author 161 | #' @export 162 | vec_ptype2.character.projects_author <- function(x, y, ...) character() 163 | 164 | #' @method vec_cast projects_author 165 | #' @export vec_cast.projects_author 166 | #' @export 167 | #' @rdname projects_author-vctrs 168 | vec_cast.projects_author <- function(x, to, ...) 169 | UseMethod("vec_cast.projects_author") 170 | 171 | #' @method vec_cast.projects_author default 172 | #' @export 173 | vec_cast.projects_author.default <- function(x, to, ...) 174 | vec_default_cast(x, to) 175 | 176 | #' @method vec_cast.projects_author projects_author 177 | #' @export 178 | vec_cast.projects_author.projects_author <- function(x, to, ...) x 179 | 180 | #' @method vec_cast.projects_author character 181 | #' @export 182 | vec_cast.projects_author.character <- function(x, to, ...) 183 | validate_projects_author(x) 184 | 185 | #' @method vec_cast.character projects_author 186 | #' @export 187 | vec_cast.character.projects_author <- function(x, to, ...) vec_data(x) 188 | 189 | #' @method vec_cast.projects_author integer 190 | #' @export 191 | vec_cast.projects_author.integer <- function(x, ...) 192 | validate_projects_author(x) 193 | 194 | #' @method vec_cast.integer projects_author 195 | #' @export 196 | vec_cast.integer.projects_author <- function(x, ...) 197 | as.integer(stringr::str_extract(vec_data(x), "^\\d+")) 198 | 199 | #' @method vec_cast.double projects_author 200 | #' @export 201 | vec_cast.double.projects_author <- function(x, ...) 202 | as.double(stringr::str_extract(vec_data(x), "^\\d+")) 203 | 204 | 205 | #' @export 206 | Ops.projects_author <- function(e1, e2) { 207 | 208 | if (!any(c("==", "!=") == .Generic)) { 209 | stop(gettextf("%s not meaningful for projects_authors", sQuote(.Generic))) 210 | } 211 | 212 | if (rlang::is_integerish(e1) || rlang::is_integerish(e2)) { 213 | e1 <- as.integer(e1) 214 | e2 <- as.integer(e2) 215 | } else if (inherits(e1, "projects_author")) { 216 | e1 <- as.integer(e1) 217 | if (inherits(e2, "projects_author")) { 218 | e2 <- as.integer(e2) 219 | } else { 220 | e2 <- 221 | vapply( 222 | e2, 223 | function(x) as.integer(validate_projects_author(x)), 224 | integer(1L), 225 | USE.NAMES = FALSE 226 | ) 227 | } 228 | } else { 229 | e1 <- 230 | vapply( 231 | e1, 232 | function(x) as.integer(validate_projects_author(x)), 233 | integer(1L), 234 | USE.NAMES = FALSE 235 | ) 236 | e2 <- as.integer(e2) 237 | } 238 | 239 | get(.Generic)(e1, e2) 240 | } 241 | 242 | 243 | 244 | # Generic methods for match() -------------------------------------------------- 245 | 246 | #' @rdname projects_author 247 | #' @export 248 | match.projects_author <- function(x, 249 | table, 250 | nomatch = NA_integer_, 251 | incomparables = NULL) { 252 | 253 | if (rlang::is_integerish(x) || rlang::is_integerish(table)) { 254 | x <- as.integer(x) 255 | table <- as.integer(table) 256 | if (!is.null(incomparables)) { 257 | if (!rlang::is_integerish(incomparables)) { 258 | incomparables <- lapply(incomparables, validate_projects_author) 259 | } 260 | incomparables <- as.integer(incomparables) 261 | } 262 | } else { 263 | if (inherits(x, "projects_author")) { 264 | if (!inherits(table, "projects_author")) { 265 | table <- lapply(table, validate_projects_author) 266 | } 267 | } else { 268 | x <- lapply(x, validate_projects_author) 269 | } 270 | if (!is.null(incomparables)) { 271 | incomparables <- lapply(incomparables, validate_projects_author) 272 | } 273 | } 274 | 275 | base::match(x, table, nomatch, incomparables) 276 | } 277 | 278 | #' @include set_generics.R 279 | #' @rdname projects_author 280 | #' @export 281 | methods::setMethod( 282 | "match", 283 | methods::signature(x = "projects_author"), 284 | match.projects_author 285 | ) 286 | 287 | #' @include set_generics.R 288 | #' @rdname projects_author 289 | #' @export 290 | methods::setMethod( 291 | "match", 292 | methods::signature(table = "projects_author"), 293 | match.projects_author 294 | ) 295 | 296 | #' @include set_generics.R 297 | #' @rdname projects_author 298 | #' @export 299 | methods::setMethod( 300 | "match", 301 | methods::signature(x = "projects_author", table = "projects_author"), 302 | match.projects_author 303 | ) 304 | 305 | 306 | 307 | 308 | # Generic methods for %in% ----------------------------------------------------- 309 | 310 | #' @rdname projects_author 311 | #' @export 312 | `%in%.projects_author` <- function(x, table) { 313 | match(x, table, nomatch = 0L) > 0L 314 | } 315 | 316 | #' @include set_generics.R 317 | #' @rdname projects_author 318 | #' @export 319 | methods::setMethod( 320 | "%in%", 321 | methods::signature("projects_author"), 322 | `%in%.projects_author` 323 | ) 324 | 325 | #' Internal vctrs methods 326 | #' 327 | #' @import vctrs 328 | #' @keywords internal 329 | #' @name projects_author-vctrs 330 | NULL 331 | -------------------------------------------------------------------------------- /R/class-projects_stage.R: -------------------------------------------------------------------------------- 1 | 2 | #' \code{projects_stage} vector 3 | #' 4 | #' Objects of this class are merely a character string containing a number and a 5 | #' name of one of seven project development stages. 6 | #' 7 | #' A \code{projects_stage} object is either a missing value (\code{NA}) or one 8 | #' of: 9 | #' 10 | #' \code{0: idea}\cr \code{1: design}\cr \code{2: data collection}\cr \code{3: 11 | #' analysis}\cr \code{4: manuscript}\cr \code{5: under review}\cr \code{6: 12 | #' accepted} 13 | #' 14 | #' \code{projects_stage()} validates and coerces a vector of the above integers or strings to a \code{projects_stage} S3 vector. 15 | #' 16 | #' @section Numeric coercion methods: \code{\link{as.integer}()}, 17 | #' \code{\link{as.double}()}, and \code{\link{as.numeric}()} return the stage 18 | #' number of the \code{projects_stage} object as an integer/double. The 19 | #' methods for the comparison and value matching functions described below 20 | #' make use of these numeric coercion methods. Users desiring to apply value 21 | #' matching functions other than the ones described below may similarly take 22 | #' advantage of these. 23 | #' 24 | #' @section Comparison and value matching methods: Methods for the 25 | #' \link{Comparison} operators as well as \code{\link{match}()} and 26 | #' \code{\link{\%in\%}} enable users to test equality and to value match among 27 | #' \code{projects_stage} objects and as well as between \code{projects_stage} 28 | #' objects and unclassed numbers/characters. When comparing or value matching 29 | #' against a numeric vector, the \code{projects_stage} object is first coerced 30 | #' to an integer with the \code{as.integer()} method described above. When 31 | #' testing or value matching against a character vector, the character vector 32 | #' is validated against the list of project stages enumerated above. 33 | #' 34 | #' @param x For \code{projects_stage()}, an integer or character vector. For 35 | #' 36 | #' For \code{\link{match}()} and \code{\link{\%in\%}}, an integer, a character 37 | #' string, or a \code{projects_stage} object. See \code{\link{match}()} and 38 | #' \strong{Comparison and value matching methods} below. 39 | #' 40 | #' @param table An integer number, a character string, or a 41 | #' \code{projects_stage} object. See \code{\link{match}()} and 42 | #' \strong{Comparison and value matching methods} below. 43 | #' 44 | #' @param nomatch See \code{\link{match}()}. 45 | #' 46 | #' @param incomparables An integer number, a character string, or a 47 | #' \code{projects_stage} object. See \code{\link{match}()}. 48 | #' 49 | #' @return For \code{projects_stage()}, an S3 vector of class 50 | #' \code{projects_stage}. 51 | #' 52 | #' @seealso \code{\link{Ops}}; \code{\link[methods]{Methods_for_Nongenerics}}. 53 | #' 54 | #' @examples 55 | #' stage <- projects_stage("4: manuscript") 56 | #' 57 | #' as.integer(stage) # 4 58 | #' 59 | #' stage == 4 # TRUE 60 | #' stage != 4 # FALSE 61 | #' stage < 6 # TRUE 62 | #' 63 | #' stage %in% c(3:6) # TRUE 64 | #' match(stage, 0:4) # 5 65 | #' 66 | #' stage %in% c("design", "manusc", "idea") # TRUE 67 | #' 68 | #' more_stages <- projects_stage(c("0: idea", "4: manuscript", "1: design")) 69 | #' 70 | #' match("MAnuscRIPT", more_stages) # 2 71 | #' @export 72 | projects_stage <- function(x = character()) { 73 | x <- as.character(x) 74 | validate_stage(x) 75 | } 76 | 77 | 78 | new_projects_stage <- function(x = character()) { 79 | vec_assert(x, character()) 80 | new_vctr(x, class = "projects_stage") 81 | } 82 | 83 | 84 | #' @rdname projects_stage 85 | #' @export 86 | methods::setClass("projects_stage") 87 | 88 | 89 | #' @export 90 | vec_ptype_abbr.projects_stage <- function(x, ...) "prjstg" 91 | 92 | 93 | validate_stage <- function(stage, na.ok = TRUE, null.ok = FALSE, n = NULL) { 94 | 95 | if (is.null(stage) && null.ok) { 96 | return(NULL) 97 | } 98 | 99 | choices <- eval(formals(new_project)$stage) 100 | 101 | stage <- trimws(tolower(as.character(stage))) 102 | 103 | if (!rlang::is_atomic(stage) || !is.null(n) && length(stage) != n) { 104 | stop("\nstage must be coercible to a character vector of length ", n) 105 | } 106 | 107 | stage <- 108 | vapply( 109 | stage, 110 | function(stage) { 111 | if (is.na(stage)) { 112 | if (!na.ok) { 113 | stop("stage must not be missing (NA)") 114 | } 115 | } else { 116 | 117 | match_attempt <- pmatch(stage, choices) 118 | 119 | if (is.na(match_attempt)) { 120 | 121 | match_attempt <- pmatch(stage, substr(choices, 4L, nchar(choices))) 122 | 123 | if (is.na(match_attempt)) { 124 | stop( 125 | "\nTo match a stage, user input must either:\n\n", 126 | "- exactly match the integer\n", 127 | "- partially match the text\n\n", 128 | "of one of:\n", 129 | paste(choices, collapse = "\n"), 130 | "\n\n'", stage, "' did not match." 131 | ) 132 | } 133 | } 134 | 135 | stage <- choices[match_attempt] 136 | } 137 | }, 138 | FUN.VALUE = character(1L), 139 | USE.NAMES = FALSE 140 | ) 141 | 142 | new_projects_stage(stage) 143 | } 144 | 145 | 146 | 147 | #' @rdname projects_stage-vctrs 148 | #' @method vec_ptype2 projects_stage 149 | #' @export 150 | #' @export vec_ptype2.projects_stage 151 | vec_ptype2.projects_stage <- function(x, y, ...) 152 | UseMethod("vec_ptype2.projects_stage", y) 153 | 154 | #' @method vec_ptype2.projects_stage default 155 | #' @export 156 | vec_ptype2.projects_stage.default <- function(x, y, ..., 157 | x_arg = "x", y_arg = "y") 158 | vec_default_ptype2(x, y, x_arg = x_arg, y_arg = y_arg) 159 | 160 | #' @method vec_ptype2.projects_stage projects_stage 161 | #' @export 162 | vec_ptype2.projects_stage.projects_stage <- function(x, y, ...) 163 | new_projects_stage() 164 | 165 | #' @method vec_ptype2.projects_stage character 166 | #' @export 167 | vec_ptype2.projects_stage.character <- function(x, y, ...) character() 168 | 169 | #' @method vec_ptype2.character projects_stage 170 | #' @export 171 | vec_ptype2.character.projects_stage <- function(x, y, ...) character() 172 | 173 | #' @method vec_cast projects_stage 174 | #' @export vec_cast.projects_stage 175 | #' @export 176 | #' @rdname projects_stage-vctrs 177 | vec_cast.projects_stage <- function(x, to, ...) 178 | UseMethod("vec_cast.projects_stage") 179 | 180 | #' @method vec_cast.projects_stage default 181 | #' @export 182 | vec_cast.projects_stage.default <- function(x, to, ...) 183 | vec_default_cast(x, to) 184 | 185 | #' @method vec_cast.projects_stage projects_stage 186 | #' @export 187 | vec_cast.projects_stage.projects_stage <- function(x, to, ...) x 188 | 189 | #' @method vec_cast.projects_stage character 190 | #' @export 191 | vec_cast.projects_stage.character <- function(x, to, ...) validate_stage(x) 192 | 193 | #' @method vec_cast.character projects_stage 194 | #' @export 195 | vec_cast.character.projects_stage <- function(x, to, ...) vec_data(x) 196 | 197 | #' @method vec_cast.projects_stage integer 198 | #' @export 199 | vec_cast.projects_stage.integer <- function(x, ...) validate_stage(x) 200 | 201 | #' @method vec_cast.integer projects_stage 202 | #' @export 203 | vec_cast.integer.projects_stage <- function(x, ...) 204 | as.integer(substr(vec_data(x), 1L, 1L)) 205 | 206 | #' @method vec_cast.double projects_stage 207 | #' @export 208 | vec_cast.double.projects_stage <- function(x, ...) 209 | as.double(substr(vec_data(x), 1L, 1L)) 210 | 211 | #' @method vec_cast.projects_stage double 212 | #' @export 213 | vec_cast.projects_stage.double <- function(x, ...) validate_stage(x) 214 | 215 | 216 | #' @export 217 | Ops.projects_stage <- function(e1, e2) { 218 | get(.Generic)( 219 | vapply(validate_stage(e1), as.integer, 0L), 220 | vapply(validate_stage(e2), as.integer, 0L) 221 | ) 222 | } 223 | 224 | 225 | 226 | 227 | # Generic methods for match() -------------------------------------------------- 228 | 229 | #' @rdname projects_stage 230 | #' @export 231 | match.projects_stage <- function(x, 232 | table, 233 | nomatch = NA_integer_, 234 | incomparables = NULL) { 235 | 236 | x <- validate_stage(x) 237 | table <- validate_stage(table) 238 | if (!is.null(incomparables)) { 239 | incomparables <- validate_stage(incomparables) 240 | } 241 | 242 | base::match(x, table, nomatch, incomparables) 243 | } 244 | 245 | #' @include set_generics.R 246 | #' @rdname projects_stage 247 | #' @export 248 | methods::setMethod( 249 | "match", 250 | methods::signature(x = "projects_stage"), 251 | match.projects_stage 252 | ) 253 | 254 | #' @include set_generics.R 255 | #' @rdname projects_stage 256 | #' @export 257 | methods::setMethod( 258 | "match", 259 | methods::signature(table = "projects_stage"), 260 | match.projects_stage 261 | ) 262 | 263 | #' @include set_generics.R 264 | #' @rdname projects_stage 265 | #' @export 266 | methods::setMethod( 267 | "match", 268 | methods::signature(x = "projects_stage", table = "projects_stage"), 269 | match.projects_stage 270 | ) 271 | 272 | 273 | 274 | 275 | 276 | # Generic methods for %in% ----------------------------------------------------- 277 | 278 | #' @rdname projects_stage 279 | #' @export 280 | `%in%.projects_stage` <- function(x, table) { 281 | match(x, table, nomatch = 0L) > 0L 282 | } 283 | 284 | #' @include set_generics.R 285 | #' @rdname projects_stage 286 | #' @export 287 | methods::setMethod( 288 | "%in%", 289 | methods::signature("projects_stage"), 290 | `%in%.projects_stage` 291 | ) 292 | 293 | #' Internal vctrs methods 294 | #' 295 | #' @import vctrs 296 | #' @keywords internal 297 | #' @name projects_stage-vctrs 298 | NULL 299 | -------------------------------------------------------------------------------- /R/email_authors.R: -------------------------------------------------------------------------------- 1 | 2 | #' Write an email to project authors 3 | #' 4 | #' Invokes \code{utils::\link[utils]{browseURL}("mailto://[author emails]")} for 5 | #' a specified project, or for the currently open project if \code{project} is 6 | #' left as \code{NULL}. 7 | #' 8 | #' The success of this function depends on the platform and the specified 9 | #' \code{browser}. See the \strong{Details} and \strong{URL schemes} sections of 10 | #' \code{utils::\link[utils]{browseURL}()}. 11 | #' 12 | #' If \code{project = NULL}, the function selects the project in the 13 | #' \code{\link{projects}()} table whose \code{path} is equal to 14 | #' \code{rstudioapi::\link[rstudioapi]{getActiveProject}()}. 15 | #' 16 | #' @param project Project \code{id} or unambiguous substring of the project name 17 | #' from the \code{\link{projects}()} table. Defaults to \code{NULL} (see 18 | #' \strong{Details}). 19 | #' @param browser,encodeIfNeeded See \code{utils::\link[utils]{browseURL}()}. 20 | #' 21 | #' @seealso \code{utils::\link[utils]{browseURL}()}; 22 | #' \code{rstudioapi::\link[rstudioapi]{getActiveProject}()} for information on 23 | #' \code{browser} and \code{encodeIfNeeded} arguments. 24 | #' 25 | #' @examples 26 | #' # Wrapped in if (interactive()) because this function is interactive by nature. 27 | #' if (interactive()) { 28 | #' 29 | #' # If you have a projects() project open, just run it: 30 | #' email_authors() 31 | #' 32 | #' # Otherwise, specify a project: 33 | #' 34 | #' ########################################################################### 35 | #' # Setup 36 | #' old_home <- Sys.getenv("HOME") 37 | #' old_ppath <- Sys.getenv("PROJECTS_FOLDER_PATH") 38 | #' temp_dir <- tempfile("dir") 39 | #' dir.create(temp_dir) 40 | #' Sys.unsetenv("PROJECTS_FOLDER_PATH") 41 | #' Sys.setenv(HOME = temp_dir) 42 | #' setup_projects(path = temp_dir) 43 | #' new_author("Rhonda", "Rondale", email = "ronda.rondale@co.uk") 44 | #' new_author("Betty", "Betts", email = "betty@co.uk") 45 | #' new_project("Inventing the Ring of Power", authors = c("Betty", "Ron")) 46 | #' ########################################################################### 47 | #' 48 | #' email_authors("Ring of Power") 49 | #' 50 | #' ########################################################################### 51 | #' # Cleanup (or just restart R) 52 | #' Sys.setenv(HOME = old_home, PROJECTS_FOLDER_PATH = old_ppath) 53 | #' } 54 | #' @importFrom rlang .data 55 | #' @export 56 | email_authors <- function(project = NULL, 57 | browser = getOption("browser"), 58 | encodeIfNeeded = FALSE) { 59 | 60 | p_path <- get_p_path() 61 | 62 | projects_table <- projects_internal(p_path, archived = TRUE) 63 | authors_table <- authors_internal(p_path) 64 | pa_assoc <- pa_assoc_internal(p_path) 65 | 66 | if (is.null(project)) { 67 | project_id <- 68 | dplyr::filter( 69 | projects_table, 70 | .data$path == rstudioapi::getActiveProject() 71 | )$id 72 | 73 | if (length(project_id) != 1L) { 74 | if (length(project_id) == 0L) { 75 | stop( 76 | "No project found in the projects() table with the path:\n", 77 | rstudioapi::getActiveProject() 78 | ) 79 | } else { 80 | stop( 81 | "Multiple projects found in the projects() table with the path:\n", 82 | rstudioapi::getActiveProject() 83 | ) 84 | } 85 | } 86 | 87 | } else { 88 | project_id <- 89 | validate_unique_entry( 90 | x = project, 91 | table = projects_table, 92 | what = "project" 93 | )$id 94 | } 95 | 96 | author_ids <- dplyr::filter(pa_assoc, .data$id1 == project_id)$id2 97 | 98 | if (length(author_ids) == 0L) { 99 | print(dplyr::filter(projects_table, .data$id == project_id)) 100 | stop("\nThe above project has no authors.") 101 | } 102 | 103 | author_emails <- 104 | authors_table %>% 105 | dplyr::filter(.data$id %in% author_ids & !is.na(.data$email)) %>% 106 | `[[`("email") 107 | 108 | if (length(author_emails) == 0L) { 109 | print(dplyr::filter(projects_table, .data$id == project_id)) 110 | print(dplyr::filter(authors_table, .data$id %in% author_ids)) 111 | stop("\nThe above authors of the above project have no email addresses.") 112 | } 113 | 114 | url <- paste0("mailto://", paste(author_emails, collapse = ", ")) 115 | 116 | utils::browseURL(url, browser, encodeIfNeeded) 117 | } 118 | -------------------------------------------------------------------------------- /R/header.R: -------------------------------------------------------------------------------- 1 | 2 | #' Print project header to console 3 | #' 4 | #' Prints a header to the console to be copied and pasted into the YAML of a 5 | #' project protocol or manuscript R Markdown file. These lines essentially 6 | #' produce a title page when the R Markdown file is knitted. 7 | #' 8 | #' The project header consists of: 9 | #' 10 | #' \enumerate{ 11 | #' 12 | #' \item the project title 13 | #' 14 | #' \item the author list 15 | #' 16 | #' \item the list of author affiliations 17 | #' 18 | #' \item corresponding author information 19 | #' 20 | #' } 21 | #' 22 | #' @param project Project \code{id} or unambiguous substring of the project name 23 | #' from the \code{\link{projects}()} table. 24 | #' @param archived Logical, indicating whether or not the function should 25 | #' consider archived projects when determining which project the user is 26 | #' referring to in the \code{project} argument. \code{FALSE} by default. 27 | #' 28 | #' See the \strong{Details} section of \code{\link{archive_project}()} for 29 | #' more information on the "archived" status of a project. 30 | #' 31 | #' @examples 32 | #' ############################################################################# 33 | #' # SETUP 34 | #' old_home <- Sys.getenv("HOME") 35 | #' old_ppath <- Sys.getenv("PROJECTS_FOLDER_PATH") 36 | #' temp_dir <- tempfile("dir") 37 | #' dir.create(temp_dir) 38 | #' Sys.unsetenv("PROJECTS_FOLDER_PATH") 39 | #' Sys.setenv(HOME = temp_dir) 40 | #' setup_projects(path = temp_dir) 41 | #' new_affiliation(department_name = "Math Dept.", 42 | #' institution_name = "Springfield College", 43 | #' address = "123 College St, Springfield, AB") 44 | #' new_affiliation(department_name = "Art Department", 45 | #' institution_name = "Springfield College", 46 | #' address = "321 University Boulevard, Springfield, AB", 47 | #' id = 42) 48 | #' new_affiliation(department_name = "Central Intelligence Agency", 49 | #' institution_name = "United States Government", 50 | #' address = "888 Classified Dr, Washington DC") 51 | #' new_affiliation(department_name = "Pyrotechnics", 52 | #' institution_name = "ACME") 53 | #' new_author(given_names = "Rosetta", last_name = "Stone", 54 | #' affiliations = c(42, "Math"), degree = "PhD", 55 | #' email = "slab@rock.net", phone = "867-555-5309", id = 8888) 56 | #' new_author(given_names = "Spiro", last_name = "Agnew", degree = "LLB", 57 | #' affiliations = "Art D", id = 13) 58 | #' new_author(given_names = "Plato", id = 303) 59 | #' new_project(title = "Test Project 1", authors = c(13, "303", "Stone"), 60 | #' corresp_auth = "Stone") 61 | #' ############################################################################# 62 | #' 63 | #' header(1) 64 | #' 65 | #' ############################################################################# 66 | #' # CLEANUP 67 | #' Sys.setenv(HOME = old_home, PROJECTS_FOLDER_PATH = old_ppath) 68 | #' @name header 69 | #' @export 70 | header <- function(project, 71 | archived = FALSE 72 | # degree = TRUE, 73 | # corresp_address = TRUE, 74 | # corresp_phone = FALSE, 75 | # corresp_email = TRUE 76 | ) { 77 | 78 | p_path <- get_p_path() 79 | 80 | projects_table <- projects_internal(archived = archived) 81 | 82 | project_row <- 83 | validate_unique_entry(project, table = projects_table, what = "project") 84 | 85 | print_header_internal( 86 | project_id = project_row$id, 87 | p_path = p_path, 88 | project_row = project_row 89 | # degree = degree, 90 | # corresp_address = corresp_address, 91 | # corresp_phone = corresp_phone, 92 | # corresp_email = corresp_email 93 | ) 94 | } 95 | 96 | 97 | 98 | #' @importFrom rlang .data 99 | print_header_internal <- function( 100 | 101 | project_id, 102 | p_path = get_p_path(), 103 | project_row = dplyr::filter(projects_internal(p_path, TRUE), 104 | .data$id == project_id), 105 | authors_table = authors_internal(p_path), 106 | affiliations_table = affiliations_internal(p_path), 107 | project_author_assoc = pa_assoc_internal(p_path), 108 | author_affiliation_assoc = aa_assoc_internal(p_path) 109 | # degree, 110 | # corresp_address, 111 | # corresp_phone, 112 | # corresp_email 113 | ) { 114 | 115 | project_authors <- 116 | project_author_assoc$id2[project_author_assoc$id1 == project_id] 117 | 118 | corresp_auth_row <- 119 | authors_table[match(project_row$corresp_auth, authors_table$id), ] 120 | 121 | taa_to_console( 122 | title = project_row$title, 123 | header = 124 | aa_header( 125 | project_id = project_id, 126 | corresp_auth_row = corresp_auth_row, 127 | authors_table = authors_table, 128 | affiliations_table = affiliations_table, 129 | project_authors = project_authors, 130 | author_affiliation_assoc = author_affiliation_assoc 131 | # degree = degree, 132 | # corresp_address = corresp_address, 133 | # corresp_phone = corresp_phone, 134 | # corresp_email = corresp_email 135 | ) 136 | ) 137 | } 138 | 139 | 140 | 141 | taa_to_console <- function(title, header) { 142 | cat('\ntitle: "', title, '"\n', sep = "") 143 | cat(header, sep = '\n') 144 | } 145 | 146 | 147 | 148 | #' @importFrom rlang .data 149 | aa_header <- function(project_id, 150 | corresp_auth_row, 151 | authors_table, 152 | affiliations_table, 153 | project_authors, 154 | author_affiliation_assoc 155 | # degree, 156 | # corresp_address, 157 | # corresp_phone, 158 | # corresp_email 159 | ) { 160 | 161 | # The left_join/select/rename combo was used instead of semi_join so that the 162 | # order in project_author_assoc would be preserved 163 | project_authors <- 164 | dplyr::left_join( 165 | tibble::tibble(id = project_authors), 166 | authors_table, 167 | by = "id" 168 | ) 169 | 170 | # In effect, this is author_affiliations_assoc (1) filtered to only include 171 | # authors on the project who have at least one affiliation and (2) all 172 | # affiliation information filled in. 173 | # It is constructed using the command sequence below in order to preserve (1) 174 | # the order of authors on the project and (2) the order of the affiliations of 175 | # each author. 176 | aa_assoc_complete <- 177 | project_authors %>% 178 | dplyr::select("id1" = "id") %>% 179 | dplyr::inner_join(author_affiliation_assoc, by = "id1") %>% 180 | dplyr::left_join(affiliations_table, by = c("id2" = "id")) 181 | 182 | 183 | if (nrow(project_authors) > 0L) { 184 | ############################################################ 185 | # Construction of affiliations line to go in 01_protocol.Rmd 186 | 187 | if (nrow(aa_assoc_complete) > 0L) { 188 | 189 | # A tibble of the unique affiliations associated with the project, with a 190 | # superscript assigned to each 191 | unique_affiliations <- 192 | aa_assoc_complete %>% 193 | dplyr::select(-"id1") %>% 194 | dplyr::distinct() %>% 195 | dplyr::mutate(superscript = dplyr::row_number()) 196 | 197 | # In effect this adds the superscripts created in the previous command to 198 | # aa_assoc_complete 199 | aa_assoc_complete <- 200 | unique_affiliations %>% 201 | dplyr::select(.data$id2, .data$superscript) %>% 202 | dplyr::right_join(aa_assoc_complete, by = "id2") 203 | 204 | 205 | affiliations_lines <- character() 206 | for (a in seq_len(nrow(unique_affiliations))) { 207 | 208 | affiliation_line <- paste0(" - ^", a, "^ ", 209 | unique_affiliations$department_name[a]) 210 | 211 | if (!is.na(unique_affiliations$institution_name[a])) { 212 | affiliation_line <- paste0(affiliation_line, ", ", 213 | unique_affiliations$institution_name[a]) 214 | } 215 | 216 | if (!is.na(unique_affiliations$address[a])) { 217 | affiliation_line <- paste0(affiliation_line, ", ", 218 | unique_affiliations$address[a]) 219 | } 220 | 221 | affiliations_lines <- append(affiliations_lines, affiliation_line) 222 | } 223 | } 224 | else { 225 | affiliations_lines <- character() 226 | } 227 | 228 | ###################################################### 229 | ###################################################### 230 | 231 | author_line <- " - " 232 | 233 | for (x in seq_len(nrow(project_authors))) { 234 | 235 | if (x != 1) { 236 | author_line <- paste0(author_line, " ") 237 | 238 | if (x == nrow(project_authors) && x > 1) { 239 | author_line <- paste0(author_line, "and ") 240 | } 241 | } 242 | 243 | first_piece <- TRUE 244 | 245 | if (!is.na(project_authors$given_names[x])) { 246 | author_line <- paste0(author_line, project_authors$given_names[x]) 247 | first_piece <- FALSE 248 | } 249 | 250 | if (!is.na(project_authors$last_name[x])) { 251 | if (!first_piece) { 252 | author_line <- paste0(author_line, " ") 253 | } 254 | 255 | author_line <- paste0(author_line, project_authors$last_name[x]) 256 | } 257 | 258 | if ( 259 | # degree && 260 | !is.na(project_authors$degree[x])) { 261 | author_line <- paste0(author_line, ", ", project_authors$degree[x]) 262 | } 263 | 264 | if (x != nrow(project_authors) && nrow(project_authors) > 2L) { 265 | author_line <- paste0(author_line, ";") 266 | } 267 | 268 | x_affiliations <- 269 | dplyr::filter(aa_assoc_complete, .data$id1 == project_authors$id[x]) 270 | 271 | if (nrow(x_affiliations) > 0L) { 272 | author_line <- 273 | paste0( 274 | author_line, 275 | "^", 276 | paste(sort(x_affiliations$superscript), collapse = ","), 277 | "^" 278 | ) 279 | } 280 | 281 | if (isTRUE(project_authors$id[x] == corresp_auth_row$id)) { 282 | author_line <- paste0(author_line, "\\*") 283 | } 284 | } 285 | 286 | if (is.null(corresp_auth_row)) { 287 | corresp_lines <- character() 288 | } else { 289 | corresp_affils <- 290 | aa_assoc_complete[match(corresp_auth_row$id, aa_assoc_complete$id1), ] 291 | 292 | corresp_lines <- " - \\* Corresponding author" 293 | 294 | if ( 295 | # corresp_address && 296 | nrow(corresp_affils) > 0L && 297 | length(stats::na.omit(corresp_affils$address)) > 0L) { 298 | corresp_lines <- 299 | append( 300 | corresp_lines, 301 | paste0( 302 | " - ", 303 | corresp_affils$address[!is.na(corresp_affils$address)][1L] 304 | ) 305 | ) 306 | } 307 | 308 | if ( 309 | # corresp_phone && 310 | !is.na(corresp_auth_row$phone)) { 311 | corresp_lines <- 312 | append(corresp_lines, paste0(" - ", corresp_auth_row$phone)) 313 | } 314 | 315 | if ( 316 | # corresp_email && 317 | !is.na(corresp_auth_row$email)) { 318 | corresp_lines <- 319 | append(corresp_lines, paste0(" - ", corresp_auth_row$email)) 320 | } 321 | } 322 | 323 | c("author:", author_line, affiliations_lines, corresp_lines) 324 | } else { 325 | character() 326 | } 327 | } 328 | -------------------------------------------------------------------------------- /R/metadata_manipulation.R: -------------------------------------------------------------------------------- 1 | 2 | make_rds_path <- function(rds_name, p_path = get_p_path()) { 3 | fs::path(p_path, ".metadata", rds_name, ext = "rds") 4 | } 5 | 6 | 7 | 8 | get_rds <- function(rds_path) { 9 | 10 | if (!fs::file_exists(rds_path)) { 11 | 12 | what <- fs::path_ext_remove(fs::path_file(rds_path)) 13 | 14 | user_prompt( 15 | msg = 16 | paste0("\nThe ", what, " table was not found at\n", rds_path, 17 | "\n\nContinue with a blank ", what, " table?"), 18 | n_msg = 19 | paste0("\n\nRestore the ", what, " table to\n", rds_path, 20 | "\n\nOr, [re]run setup_projects()", 21 | "\n\nOr, just put 'y' next time.") 22 | ) 23 | switch( 24 | what, 25 | projects = projects_ptype, 26 | authors = authors_ptype, 27 | affiliations = affiliations_ptype, 28 | tasks = tasks_ptype, 29 | assoc_ptype 30 | ) 31 | } else { 32 | readRDS(rds_path) 33 | } 34 | } 35 | 36 | 37 | 38 | save_metadata <- function(x, path, .ptype) { 39 | readr::write_rds(vec_cast(x, .ptype), path) 40 | } 41 | 42 | 43 | 44 | projects_internal <- function(p_path = get_p_path(), archived = TRUE) { 45 | 46 | projects_table <- get_rds(make_rds_path("projects", p_path)) 47 | 48 | if (archived) { 49 | projects_table 50 | } else { 51 | remove_archived(projects_table) 52 | } 53 | } 54 | 55 | tasks_internal <- function(p_path = get_p_path()) { 56 | get_rds(make_rds_path("tasks", p_path)) 57 | } 58 | 59 | authors_internal <- function(p_path = get_p_path()) { 60 | get_rds(make_rds_path("authors", p_path)) 61 | } 62 | 63 | affiliations_internal <- function(p_path = get_p_path()) { 64 | get_rds(make_rds_path("affiliations", p_path)) 65 | } 66 | 67 | pa_assoc_internal <- function(p_path = get_p_path()) { 68 | get_rds(make_rds_path("project_author_assoc", p_path)) 69 | } 70 | 71 | aa_assoc_internal <- function(p_path = get_p_path()) { 72 | get_rds(make_rds_path("author_affiliation_assoc", p_path)) 73 | } 74 | 75 | 76 | 77 | add_metadata <- function(table, 78 | new_row, 79 | table_path, 80 | .ptype, 81 | task = FALSE) { 82 | 83 | if (task) { 84 | table <- table %>% 85 | vec_rbind(new_row, .ptype = dplyr::mutate(.ptype, TID = double())) %>% 86 | sort_project_tasks(PID = new_row$PID) 87 | } else { 88 | table <- vec_rbind(table, new_row) 89 | } 90 | 91 | save_metadata(table, table_path, .ptype) 92 | 93 | table 94 | } 95 | 96 | 97 | edit_metadata <- function(table, row_spec_lgl, table_path, .ptype, ...) { 98 | 99 | changes <- list(...) 100 | 101 | purrr::iwalk( 102 | changes, 103 | function(new_value, colname) { 104 | if (!is.null(new_value)) { 105 | table[row_spec_lgl, colname] <<- new_value 106 | } 107 | } 108 | ) 109 | 110 | if (!is.null(changes$TID)) { 111 | table <- 112 | sort_project_tasks( 113 | table, 114 | PID = table$PID[row_spec_lgl], 115 | tiebreaker = !row_spec_lgl 116 | ) 117 | } 118 | 119 | save_metadata(table, table_path, .ptype) 120 | 121 | table 122 | } 123 | 124 | 125 | 126 | add_assoc <- function(assoc_table, new_rows, assoc_path) { 127 | 128 | assoc_table <- vec_rbind(assoc_table, new_rows, .ptype = assoc_ptype) 129 | 130 | save_metadata(assoc_table, assoc_path, assoc_ptype) 131 | 132 | assoc_table 133 | } 134 | 135 | 136 | 137 | delete_assoc <- function(assoc_table, ..., assoc_path) { 138 | 139 | assoc_to_delete <- tibble::tibble(...) 140 | 141 | assoc_table <- 142 | suppressMessages( 143 | dplyr::anti_join(assoc_table, assoc_to_delete) 144 | ) 145 | 146 | save_metadata(assoc_table, assoc_path, assoc_ptype) 147 | 148 | assoc_table 149 | } 150 | 151 | 152 | 153 | change_special_author <- function(author_id, 154 | new_value, 155 | table, 156 | table_path, 157 | ptype) { 158 | if (nrow(table)) { 159 | special_author_cols <- 160 | table %>% 161 | dplyr::select(where(is_projects_author)) %>% 162 | names() 163 | change_matrix <- table[special_author_cols] == author_id 164 | if (isTRUE(any(change_matrix))) { 165 | table[special_author_cols][change_matrix] <- new_value 166 | save_metadata(table, table_path, ptype) 167 | } 168 | } 169 | } 170 | 171 | 172 | #' @importFrom rlang .data 173 | remove_archived <- function(projects_table) { 174 | dplyr::filter( 175 | projects_table, 176 | fs::path_file(fs::path_dir(.data$path)) != "archive" 177 | ) 178 | } 179 | -------------------------------------------------------------------------------- /R/projects.R: -------------------------------------------------------------------------------- 1 | #' projects: A project infrastructure for researchers. 2 | #' 3 | #' The \code{projects} package provides a project infrastructure with a focus on 4 | #' manuscript creation. It creates a project folder with a single command, 5 | #' containing subdirectories for specific components, templates for manuscripts, 6 | #' and so on. 7 | #' 8 | #' @section Knitting: There are several functions that require interactive user 9 | #' confirmation via the console. Since interactive console input is 10 | #' incompatible with knitting via R Markdown files, the \code{projects} 11 | #' package was coded such that user confirmation is bypassed when 12 | #' \code{isTRUE(getOption('knitr.in.progress')) == TRUE}. Therefore, all 13 | #' \code{projects} package functions are usable when knitting. \strong{Knit 14 | #' with caution!} 15 | #' 16 | #' @section Acknowledgements: The authors of this package acknowledge the 17 | #' support provided by members of the Northeast Ohio Cohort for 18 | #' Atherosclerotic Risk Estimation (NEOCARE) investigative team: Claudia 19 | #' Coulton, Douglas Gunzler, Darcy Freedman, Neal Dawson, Michael Rothberg, 20 | #' David Zidar, David Kaelber, Douglas Einstadter, Alex Milinovich, Monica 21 | #' Webb Hooper, Kristen Hassmiller-Lich, Ye Tian (Devin), Kristen Berg, and 22 | #' Sandy Andrukat. 23 | #' 24 | #' @section Funding: This work was supported by The National Institute on Aging 25 | #' of the National Institutes of Health under award number R01AG055480. The 26 | #' content is solely the responsibility of the authors and does not 27 | #' necessarily represent the official views of the National Institutes of 28 | #' Health. 29 | #' 30 | #' @seealso \code{\link{setup_projects}()} for getting started. 31 | #' 32 | #' @docType package 33 | #' @name projects-package 34 | NULL 35 | -------------------------------------------------------------------------------- /R/reproducibility.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | #' Save R session information 4 | #' 5 | #' Creates a dated text file (.txt) containing the contents of 6 | #' \code{sessioninfo::\link[sessioninfo]{session_info}()}. 7 | #' 8 | #' The date and time when this function was run is included in the resulting 9 | #' .txt file's name and first line. This date and time is obtained from 10 | #' \code{\link{Sys.time}()}. 11 | #' 12 | #' For the file name, hyphens (-) are removed from the date, spaces are replaced 13 | #' with underscores (_), and colons (:) are replaced with a modifier letter 14 | #' colon (U+A789). 15 | #' 16 | #' @param path_dir The full path of the directory where the session information 17 | #' text file shall be written. If it doesn't exist, it is written with 18 | #' \code{fs::\link[fs]{dir_create}()}. 19 | #' 20 | #' @return A list of two: 21 | #' 22 | #' \code{$ time :} the value of \code{\link{Sys.time}()} that the 23 | #' function used 24 | #' 25 | #' \code{$ session_info() :} the value of 26 | #' \code{sessioninfo::\link[sessioninfo]{session_info}()} that the function 27 | #' used 28 | #' 29 | #' @export 30 | save_session_info <- function(path_dir = here::here("progs", "session_info")) { 31 | 32 | if (!fs::file_exists(path_dir)) { 33 | fs::dir_create(path_dir) 34 | } 35 | 36 | time <- Sys.time() 37 | 38 | time_string <- as.character(time, usetz = TRUE) 39 | 40 | session_info <- sessioninfo::session_info() 41 | 42 | txt_lines <- 43 | utils::capture.output( 44 | cat(paste0("Run time: ", time_string, "\n\n")), 45 | session_info 46 | ) 47 | 48 | readr::write_lines( 49 | txt_lines, 50 | fs::path( 51 | path_dir, 52 | paste0( 53 | "session_info_", 54 | stringr::str_replace_all( 55 | time_string, 56 | c("-" = "", " " = "_", ":" = "\uA789") 57 | ) 58 | ), 59 | ext = "txt" 60 | ) 61 | ) %>% 62 | cat(sep = "\n") 63 | 64 | invisible( 65 | list( 66 | time = time, 67 | session_info = session_info 68 | ) 69 | ) 70 | } 71 | 72 | 73 | #' Compress a project folder 74 | #' 75 | #' Creates a compressed file out of a user-specified project folder for sharing. 76 | #' 77 | #' Currently, this function uses \code{zip::\link[zip]{zipr}()}. 78 | #' 79 | #' @param project Project \code{id} or unambiguous substring of the project name 80 | #' from the \code{\link{projects}()} table. 81 | #' @param zipfile Desired file path of the resulting compressed folder file, 82 | #' including the file's desired name and file extension. See the 83 | #' \code{zipfile} argument for the \code{zip::\link[zip]{zipr}()} function. 84 | #' @param include_hidden Logical indicating whether or not to include hidden 85 | #' folders and files (e.g., those with names that begin with a period). 86 | #' Defaults to \code{FALSE}. 87 | #' @param exclude Character vector of exact names of first-level subdirectories 88 | #' of the project folder to exclude from the resulting compressed folder file. 89 | #' 90 | #' @return The name of the created zip file, invisibly. 91 | #' 92 | #' @export 93 | export_project <- function(project, 94 | zipfile, 95 | include_hidden = FALSE, 96 | exclude = NULL) { 97 | 98 | exclude <- as.character(exclude) 99 | 100 | if (!all(nchar(exclude) > 0L)) { 101 | stop("Each element of exclude must have at least 1 character.") 102 | } 103 | 104 | project_dir <- 105 | validate_unique_entry( 106 | x = project, 107 | table = projects_internal(), 108 | what = "project" 109 | )$path 110 | 111 | files <- 112 | fs::dir_ls(project_dir, all = include_hidden) %>% 113 | `[`(!(fs::path_file(.) %in% exclude)) 114 | 115 | zip::zipr(zipfile, files = files, recurse = TRUE) 116 | } 117 | -------------------------------------------------------------------------------- /R/set_generics.R: -------------------------------------------------------------------------------- 1 | 2 | #' @export 3 | methods::setGeneric("match") 4 | 5 | #' @export 6 | methods::setGeneric("%in%") 7 | -------------------------------------------------------------------------------- /R/sysdata.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/R/sysdata.rda -------------------------------------------------------------------------------- /R/update.R: -------------------------------------------------------------------------------- 1 | 2 | #' Update the project metadata 3 | #' 4 | #' Safely updates existing project metadata to be compatible with 5 | #' \code{\link[=projects-package]{projects}} 1.X.X. 6 | #' 7 | #' Prior to \code{\link[=projects-package]{projects}} 1.X.X, the \code{stage}, 8 | #' \code{current_owner}, \code{corresp_auth}, and \code{creator} columns of the 9 | #' \code{\link{projects}()} table were different. 10 | #' 11 | #' The \code{stage} column was a \link{factor}, and users had to type stage 12 | #' names exactly, down to the integer, colon, and space. Now, this column is of 13 | #' class \code{\link{projects_stage-class}}. 14 | #' 15 | #' The latter three columns were integers corresponding to \code{id}s in the 16 | #' \code{\link{authors}()} table, so users would have to query that table if 17 | #' they did not remember which author was denoted by the integer \code{id}. 18 | #' 19 | #' @param ask Logical, indicating whether or not the user would be asked at the 20 | #' command line whether or not to proceed. Defaults to \code{TRUE}. 21 | #' 22 | #' @seealso \code{\link{projects_stage-class}}; 23 | #' \code{\link{projects_author-class}}. 24 | #' 25 | #' @importFrom rlang .data 26 | #' @export 27 | update_metadata <- function(ask = TRUE) { 28 | 29 | if (ask) { 30 | user_prompt( 31 | "\nUpdate the project metadata? (y/n)", 32 | n_msg = "Answer with 'y' next time in order to proceed.", 33 | error = TRUE 34 | ) 35 | } 36 | 37 | p_path <- get_p_path() 38 | 39 | projects_path <- make_rds_path("projects", p_path) 40 | 41 | projects_table <- readRDS(projects_path) 42 | 43 | authors_path <- make_rds_path("authors", p_path) 44 | 45 | authors_table <- readRDS(authors_path) 46 | 47 | pa_assoc_path <- make_rds_path("project_author_assoc", p_path) 48 | 49 | pa_assoc <- readRDS(pa_assoc_path) 50 | 51 | if (nrow(projects_table) == 0) { 52 | projects_table <- 53 | tibble::tibble( 54 | id = integer(), 55 | title = character(), 56 | short_title = character(), 57 | current_owner = new_projects_author(), 58 | status = character(), 59 | deadline_type = character(), 60 | deadline = lubridate::as_datetime(character()), 61 | stage = new_projects_stage(), 62 | path = character(), 63 | corresp_auth = new_projects_author(), 64 | creator = new_projects_author() 65 | ) 66 | } else { 67 | 68 | projects_table$stage <- validate_stage_column(projects_table) 69 | 70 | current_owner_results <- 71 | validate_sa_column( 72 | projects_table, 73 | "current_owner", 74 | authors_table, 75 | pa_assoc, 76 | replacements = 77 | tibble::tibble(old = character(), new = new_projects_author()) 78 | ) 79 | 80 | projects_table$current_owner <- current_owner_results$results 81 | 82 | corresp_auth_results <- 83 | validate_sa_column( 84 | projects_table, 85 | "corresp_auth", 86 | authors_table, 87 | pa_assoc, 88 | replacements = current_owner_results$replacements 89 | ) 90 | 91 | projects_table$corresp_auth <- corresp_auth_results$results 92 | 93 | creator_results <- 94 | validate_sa_column( 95 | projects_table, 96 | "creator", 97 | authors_table, 98 | pa_assoc, 99 | replacements = corresp_auth_results$replacements 100 | ) 101 | 102 | projects_table$creator <- creator_results$results 103 | } 104 | 105 | save_metadata(projects_table, projects_path, projects_ptype) 106 | 107 | message("\nProjects metadata updated.") 108 | 109 | invisible(projects_table) 110 | } 111 | 112 | 113 | 114 | validate_stage_column <- function(projects_table) { 115 | 116 | replacements <- tibble::tibble(old = character(), new = new_projects_stage()) 117 | 118 | purrr::imap( 119 | projects_table$stage, 120 | function(x, row) { 121 | 122 | match_attempt <- match(x, replacements$old) 123 | 124 | if (is.na(match_attempt)) { 125 | 126 | attempt <- try(validate_stage(x), silent = TRUE) 127 | 128 | if (inherits(attempt, "try-error")) { 129 | 130 | while (inherits(attempt, "try-error")) { 131 | print(projects_table[row, c("id", "stage", "title")]) 132 | message( 133 | "\nThe stage of the above project could not be parsed.", 134 | "\nPlease re-enter it so that it matches the number or name", 135 | "\nof one of:\n", 136 | paste(eval(formals(new_project)$stage), collapse = "\n"), 137 | "\nor enter NA to make the stage NA" 138 | ) 139 | attempt <- readLines(con = stdin(), n = 1L) 140 | if (identical(attempt, "NA")) { 141 | attempt <- new_projects_stage(NA_character_) 142 | } else { 143 | attempt <- try(validate_stage(attempt), silent = TRUE) 144 | } 145 | } 146 | 147 | replacements <<- 148 | vec_rbind( 149 | tibble::tibble( 150 | old = x, 151 | new = attempt 152 | ), 153 | replacements 154 | ) 155 | } 156 | } else { 157 | attempt <- replacements$new[match_attempt] 158 | } 159 | 160 | attempt 161 | } 162 | ) %>% 163 | do.call("c", .) 164 | } 165 | 166 | 167 | 168 | validate_sa_column <- function(projects_table, 169 | colname, 170 | authors_table, 171 | pa_assoc, 172 | replacements) { 173 | purrr::map2( 174 | projects_table[[colname]], 175 | projects_table$id, 176 | function(x, id) { 177 | 178 | project_authors <- 179 | authors_table[ 180 | match(pa_assoc$id2[pa_assoc$id1 == id], authors_table$id), 181 | ] 182 | 183 | match_replacement_attempt <- match(x, replacements$old) 184 | 185 | if ( 186 | !is.na(match_replacement_attempt) && 187 | (is_creator(replacements$new[match_replacement_attempt]) || 188 | any(project_authors$id == replacements$new[match_replacement_attempt])) 189 | ) { 190 | attempt <- replacements$new[match_replacement_attempt] 191 | } else { 192 | attempt <- x 193 | } 194 | 195 | attempt <- try_author(attempt, project_authors) 196 | 197 | if (inherits(attempt, "try-error")) { 198 | 199 | original_x <- x 200 | 201 | while (inherits(attempt, "try-error")) { 202 | 203 | message( 204 | "\nThe ", colname, " '", x, 205 | "' was unable to be matched to one of the", 206 | "\nauthors in the author list of project ", id, ":" 207 | ) 208 | 209 | print(project_authors[, 1:3]) 210 | 211 | message( 212 | "\nPlease re-enter the id number or the author name", 213 | "\nof one of these authors to be the ", colname, 214 | " of project ", id, ",", 215 | "\nor enter NA to make the ", colname, " NA.", 216 | ifelse( 217 | colname == "creator", 218 | paste0( 219 | "\nAlternatively, enter 0 to make the creator:\n0: ", 220 | original_x 221 | ), 222 | "" 223 | ) 224 | ) 225 | 226 | attempt <- readLines(con = stdin(), n = 1L) 227 | 228 | if (identical(attempt, "NA")) { 229 | attempt <- new_projects_author(NA_character_) 230 | } else if (identical(attempt, "0") && colname == "creator") { 231 | attempt <- new_projects_author(paste0("0: ", original_x)) 232 | } else { 233 | x <- attempt 234 | attempt <- try_author(attempt, project_authors) 235 | } 236 | } 237 | 238 | if ( 239 | !any(replacements$old == original_x) && 240 | inherits(try_author(original_x, authors_table), "try-error") 241 | ) { 242 | replacements <<- 243 | vec_rbind( 244 | tibble::tibble( 245 | old = original_x, 246 | new = attempt 247 | ), 248 | replacements 249 | ) 250 | } 251 | } 252 | attempt 253 | } 254 | ) %>% 255 | do.call("c", .) %>% 256 | list(replacements = replacements, results = .) 257 | } 258 | 259 | 260 | 261 | try_author <- function(x, project_authors) { 262 | try( 263 | validate_projects_author( 264 | x, 265 | authors_table = project_authors, 266 | na.ok = TRUE 267 | ), 268 | silent = TRUE 269 | ) 270 | } 271 | -------------------------------------------------------------------------------- /R/utilities.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | make_project_path <- function(project_name, path = get_p_path()) { 4 | unclass(fs::path(path, project_name)) 5 | } 6 | 7 | 8 | check_all_rds <- function() { 9 | purrr::walk( 10 | c( 11 | "affiliations", 12 | "author_affiliation_assoc", 13 | "authors", 14 | "project_author_assoc", 15 | "projects" 16 | ), 17 | function(x) { 18 | print(x) 19 | print( 20 | readRDS( 21 | fs::path(projects_folder(), ".metadata", x, ext = "rds") 22 | ) 23 | ) 24 | } 25 | ) 26 | } 27 | 28 | 29 | 30 | user_prompt <- function(msg, y_msg, n_msg, error = TRUE) { 31 | 32 | prompt <- if (isTRUE(getOption('knitr.in.progress'))) "y" 33 | 34 | while (is.null(prompt) || !any(c("y", "n") == prompt)) { 35 | if (!is.null(prompt)) { 36 | message("\nInvalid input.\n") 37 | } 38 | message(msg) 39 | prompt <- tolower(readLines(con = stdin(), n = 1L)) 40 | } 41 | 42 | if (prompt == "n") { 43 | if (error) { 44 | stop(n_msg, call. = FALSE) 45 | } else if (!missing(n_msg)) { 46 | message(n_msg) 47 | } 48 | } else if (!missing(y_msg)) { 49 | message(y_msg) 50 | } 51 | 52 | prompt == "y" 53 | } 54 | -------------------------------------------------------------------------------- /R/utils-pipe.R: -------------------------------------------------------------------------------- 1 | #' Pipe operator 2 | #' 3 | #' See \code{magrittr::\link[magrittr]{\%>\%}} for details. 4 | #' 5 | #' @name %>% 6 | #' @rdname pipe 7 | #' @keywords internal 8 | #' @export 9 | #' @importFrom magrittr %>% 10 | #' @usage lhs \%>\% rhs 11 | NULL 12 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | 2 | .onAttach <- function(libname, pkgname) { 3 | 4 | p_path <- get_p_path(error = FALSE) 5 | 6 | packageStartupMessage('projects_folder() location:\n', p_path) 7 | } 8 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | 2 | ## Development version: 3 | There were no ERRORs, WARNINGs. 4 | 5 | NOTE on some platforms objecting to `methods` being in the `Imports` list. 6 | 7 | ## Update to version 2.1.3 8 | There were no ERRORs, WARNINGs. 9 | 10 | NOTE on some platforms objecting to `methods` being in the `Imports` list. 11 | 12 | ## Update to version 2.1.2 13 | There were no ERRORs, WARNINGs. 14 | 15 | NOTE on some platforms objecting to `methods` being in the `Imports` list. 16 | 17 | ## Update to version 2.1.1 18 | There were no ERRORs, WARNINGs. 19 | 20 | NOTE on some platforms objecting to `methods` being in the `Imports` list. 21 | 22 | ## Update to version 2.1.0 23 | There were no ERRORs, WARNINGs, or NOTEs. 24 | 25 | ## Update to version 2.0.0 26 | There were no ERRORS, WARNING, or NOTES. 27 | 28 | 29 | ## Update to version 1.3.0. 30 | There were no ERRORS, WARNING, or NOTES. 31 | 32 | 33 | 34 | ## Update to version 1.1.1 (show-stopping bug fix) 35 | There were no ERRORS, WARNINGS, or NOTES. 36 | 37 | 38 | 39 | ## Update to version 1.1.0. 40 | 41 | ## R CMD check results 42 | There were no ERRORs, WARNINGs, or NOTEs. 43 | -------------------------------------------------------------------------------- /demonstration/.Renviron: -------------------------------------------------------------------------------- 1 | PROJECTS_FOLDER_PATH='/tmp/RtmpS3eJpa/demonstration/projects' 2 | -------------------------------------------------------------------------------- /demonstration/demonstration.md: -------------------------------------------------------------------------------- 1 | ‘projects’ R package demonstration 2 | ================ 3 | 4 | The user can install the `projects` package from the Comprehensive R 5 | Archive Network (CRAN): 6 | 7 | ``` r 8 | install.packages("projects") 9 | ``` 10 | 11 | The user then loads the package: 12 | 13 | ``` r 14 | library(projects) 15 | ``` 16 | 17 | ## projects_folder() location: 18 | ## projects folder not found. Please run setup_projects() 19 | 20 | As the startup message indicates, the user must run `setup_projects()` 21 | in order to initialize the */projects/* folder. The function accepts the 22 | path of the directory wherein the user would like for the */projects/* 23 | folder to dwell. Here, the user establishes the */projects/* folder in 24 | the home directory, whose name is “demonstration”: 25 | 26 | ``` r 27 | setup_projects("~") 28 | ``` 29 | 30 | ## projects folder created at 31 | ## /tmp/RtmpS3eJpa/demonstration/projects 32 | ## 33 | ## Add affiliations with new_affiliation(), 34 | ## then add authors with new_author(), 35 | ## then create projects with new_project() 36 | 37 | This mock */projects* folder has now been created in the user’s home 38 | directory, and it is also available for viewing in the 39 | [demonstration](https://github.com/NikKrieger/projects/tree/master/demonstration) 40 | folder on the `projects` GitHub. 41 | 42 | The message suggests adding affiliations and authors before creating 43 | projects because it takes marginally more user effort to change an 44 | existing project’s authorship than to specify authorship upon a 45 | project’s creation. 46 | 47 | ``` r 48 | new_affiliation( 49 | department_name = "Department of Physics", 50 | institution_name = "University of North Science", 51 | address = "314 Newton Blvd, Springfield CT 06003" 52 | ) 53 | new_affiliation( 54 | department_name = "Impossibles Investigation Team", 55 | institution_name = "Creekshirebrook Academy of Thinks", 56 | address = "Let Gade 27182, 1566 Copenhagen, Denmark" 57 | ) 58 | new_affiliation( 59 | department_name = "Statistical Consulting Unit", 60 | institution_name = "Creekshirebrook Academy of Thinks", 61 | address = "196 Normal Ave, Columbus, OH ", 62 | id = 50 63 | ) 64 | new_author( 65 | given_names = "Scott", 66 | last_name = "Bug", 67 | title = "Professor", 68 | affiliations = c(2, "Physics"), 69 | degree = "PhD", 70 | email = "scottbug@imPOSSible.net", 71 | phone = "965-555-5556" 72 | ) 73 | new_author( 74 | given_names = "Marie", 75 | last_name = "Curie", 76 | title = "Chemist", 77 | affiliations = "Unit", 78 | phone = "553-867-5309", 79 | id = 86 80 | ) 81 | new_author( 82 | given_names = "George Washington", 83 | last_name = "Carver", 84 | title = "Botanist", 85 | degree = "MS", 86 | affiliations = c(1, 2, 50), 87 | id = 1337 88 | ) 89 | new_author( 90 | given_names = "Leonardo", 91 | last_name = "da Vinci", 92 | title = "Mathematician" 93 | ) 94 | new_author( 95 | last_name = "Wu", 96 | given_names = "Chien-Shiung", 97 | title = "Physicist", 98 | affiliations = c("of North", "Statistical Consulting"), 99 | degree = "PhD", 100 | email = "wu@WU.wU" 101 | ) 102 | ## Output suppressed in knitted file for brevity 103 | ``` 104 | 105 | ``` r 106 | affiliations() 107 | ``` 108 | 109 | # A tibble: 3 x 4 110 | id department_name institution_name address 111 | 112 | 1 1 Department of Physics University of North Sc… 314 Newton Blvd, Sp… 113 | 2 2 Impossibles Investiga… Creekshirebrook Academ… Let Gade 27182, 156… 114 | 3 50 Statistical Consultin… Creekshirebrook Academ… "196 Normal Ave, Co… 115 | 116 | ``` r 117 | authors() 118 | ``` 119 | 120 | ``` 121 | # A tibble: 5 x 7 122 | id given_names last_name title degree email phone 123 | 124 | 1 1 Scott Bug Professor PhD scottbug@impo… 965-555… 125 | 2 2 Leonardo da Vinci Mathemati… 126 | 3 3 Chien-Shiung Wu Physicist PhD wu@wu.wu 127 | 4 86 Marie Curie Chemist 553-867… 128 | 5 1337 George Washing… Carver Botanist MS 129 | ``` 130 | 131 | We will now create a project called “Creating Cold Fusion”: 132 | 133 | ``` r 134 | new_project( 135 | title = "Achieving Cold Fusion", 136 | short_title = "ACF", 137 | authors = list("Bug", "Chien-Shiung", "Leonardo", 1337, 86), 138 | current_owner = "Carver", 139 | corresp_auth = "Bug", 140 | creator = "Curie", 141 | stage = "1: design", 142 | deadline_type = "Pilot study", 143 | deadline = "2020-12-31", 144 | id = 12 145 | ) 146 | ``` 147 | 148 | ``` 149 | 150 | Project 12 has been created at 151 | /tmp/RtmpS3eJpa/demonstration/projects/p0012 152 | ``` 153 | 154 | # A tibble: 1 x 6 155 | id title stage status deadline_type deadline 156 | 157 | 1 12 Achieving Col… 1: desi… just cre… Pilot study 2020-12-31 00:00:00 158 | 159 | ``` 160 | 161 | New project's authors: 162 | ``` 163 | 164 | # A tibble: 5 x 7 165 | author_id given_names last_name title degree email phone 166 | 167 | 1 1 Scott Bug Professor PhD scottbug@im… 965-555… 168 | 2 3 Chien-Shiung Wu Physicist PhD wu@wu.wu 169 | 3 2 Leonardo da Vinci Mathemat… 170 | 4 1337 George Washin… Carver Botanist MS 171 | 5 86 Marie Curie Chemist 553-867… 172 | # A tibble: 1 x 3 173 | current_owner corresp_auth creator 174 | 175 | 1 1337: Carver 1: Bug 86: Curie 176 | 177 | This creates the project folder at */demonstration/projects/p0012/*. 178 | Provided that the default project folder template was not altered, the 179 | */projects* folder should be structured as follows: 180 | 181 | /tmp/RtmpS3eJpa/demonstration 182 | └── projects 183 | └── p0012 184 | ├── data 185 | ├── data_raw 186 | ├── figures 187 | ├── manuscript 188 | ├── p0012.Rproj 189 | └── progs 190 | ├── 01_protocol.Rmd 191 | ├── 02_datawork.Rmd 192 | ├── 03_analysis.Rmd 193 | ├── 04_report.Rmd 194 | ├── citations.bib 195 | ├── style.css 196 | └── styles.docx 197 | 198 | The user may now begin work on this project. The 199 | [demonstration](https://github.com/NikKrieger/projects/tree/master/demonstration) 200 | folder on the `projects` GitHub contains this project folder, with a 201 | mock project completed in order to demonstrate workflow from 202 | 01\_protocol.Rmd to 04\_report.Rmd. 203 | -------------------------------------------------------------------------------- /demonstration/projects/.metadata/affiliations.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/.metadata/affiliations.rds -------------------------------------------------------------------------------- /demonstration/projects/.metadata/author_affiliation_assoc.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/.metadata/author_affiliation_assoc.rds -------------------------------------------------------------------------------- /demonstration/projects/.metadata/authors.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/.metadata/authors.rds -------------------------------------------------------------------------------- /demonstration/projects/.metadata/project_author_assoc.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/.metadata/project_author_assoc.rds -------------------------------------------------------------------------------- /demonstration/projects/.metadata/projects.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/.metadata/projects.rds -------------------------------------------------------------------------------- /demonstration/projects/.templates/CONSORT_protocol.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | word_document: 4 | reference_docx: styles.docx 5 | html_document: 6 | css: style.css 7 | pdf_document: 8 | default 9 | bibliography: citations.bib 10 | --- 11 | 12 | Funding: 13 | 14 | \pagebreak 15 | 16 | ```{r setup, include=FALSE} 17 | knitr::opts_chunk$set(echo = TRUE) 18 | ``` 19 | 20 | 21 | ```{r load_libraries, include=FALSE} 22 | library(projects) 23 | library(here) 24 | library(tidyverse) 25 | ``` 26 | 27 | # Abstract 28 | 1a Identification as a randomised trial in the title 29 | 1b Structured summary of trial design, methods, results, and conclusions (for specific guidance see CONSORT for abstracts) 30 | 31 | # Introduction 32 | 33 | ## Background/rationale 34 | Scientific background and explanation of rationale 35 | 36 | ## Objectives 37 | Specific objectives or hypotheses 38 | 39 | # Methods 40 | 41 | ## Trial design 42 | Description of trial design (such as parallel, factorial) including allocation ratio 43 | Important changes to methods after trial commencement (such as eligibility criteria), with reasons 44 | 45 | ## Participants 46 | Eligibility criteria for participants 47 | Settings and locations where the data were collected 48 | 49 | ## Interventions 50 | The interventions for each group with sufficient details to allow replication, including how and when they were actually administered 51 | 52 | ## Outcomes 53 | Completely defined pre-specified primary and secondary outcome measures, including how and when they were assessed 54 | Any changes to trial outcomes after the trial commenced, with reasons 55 | 56 | ## Sample size 57 | How sample size was determined 58 | When applicable, explanation of any interim analyses and stopping guidelines 59 | 60 | ## Randomisation: 61 | 62 | ### Sequence generation 63 | Method used to generate the random allocation sequence 64 | Type of randomisation; details of any restriction (such as blocking and block size) 65 | 66 | ### Allocation concealment mechanism 67 | Mechanism used to implement the random allocation sequence (such as sequentially numbered containers), describing any steps taken to conceal the sequence until interventions were assigned 68 | 69 | ### Implementation 70 | Who generated the random allocation sequence, who enrolled participants, and who assigned participants to interventions 71 | 72 | ## Blinding 73 | If done, who was blinded after assignment to interventions (for example, participants, care providers, those assessing outcomes) and how 74 | If relevant, description of the similarity of interventions 75 | 76 | ## Statistical methods 77 | Statistical methods used to compare groups for primary and secondary outcomes 78 | Methods for additional analyses, such as subgroup analyses and adjusted analyses 79 | 80 | # Results 81 | 82 | ## Participant flow (a diagram is strongly recommended) 83 | For each group, the numbers of participants who were randomly assigned, received intended treatment, and were analysed for the primary outcome 84 | For each group, losses and exclusions after randomisation, together with reasons 85 | 86 | ## Recruitment 87 | Dates defining the periods of recruitment and follow-up 88 | Why the trial ended or was stopped 89 | 90 | ## Baseline data 91 | A table showing baseline demographic and clinical characteristics for each group 92 | 93 | ## Numbers analysed 94 | For each group, number of participants (denominator) included in each analysis and whether the analysis was by original assigned groups 95 | 96 | ## Outcomes and estimation 97 | For each primary and secondary outcome, results for each group, and the estimated effect size and its precision (such as 95% confidence interval) 98 | For binary outcomes, presentation of both absolute and relative effect sizes is recommended 99 | 100 | ## Ancillary analyses 101 | Results of any other analyses performed, including subgroup analyses and adjusted analyses, distinguishing pre-specified from exploratory 102 | 103 | ## Harms 104 | All important harms or unintended effects in each group (for specific guidance see CONSORT for harms) 105 | 106 | # Discussion 107 | ## Limitations 108 | Trial limitations, addressing sources of potential bias, imprecision, and, if relevant, multiplicity of analyses 109 | 110 | ## Generalisability 111 | Generalisability (external validity, applicability) of the trial findings 112 | 113 | ## Interpretation 114 | Interpretation consistent with results, balancing benefits and harms, and considering other relevant evidence 115 | 116 | # Other information 117 | 118 | ## Registration 119 | Registration number and name of trial registry 120 | 121 | ## Protocol 122 | Where the full trial protocol can be accessed, if available 123 | 124 | ## Funding 125 | Sources of funding and other support (such as supply of drugs), role of funders 126 | 127 | \pagebreak 128 | 129 | ## References 130 | 131 | ```{r session_info, include=FALSE} 132 | save_session_info(here("progs", "session_info", "protocol")) 133 | ``` 134 | -------------------------------------------------------------------------------- /demonstration/projects/.templates/STROBE_protocol.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | word_document: 4 | reference_docx: styles.docx 5 | html_document: 6 | css: style.css 7 | pdf_document: 8 | default 9 | bibliography: citations.bib 10 | --- 11 | 12 | Funding: 13 | 14 | \pagebreak 15 | 16 | ```{r setup, include=FALSE} 17 | knitr::opts_chunk$set(echo = TRUE) 18 | ``` 19 | 20 | 21 | ```{r load_libraries, include=FALSE} 22 | library(projects) 23 | library(here) 24 | library(tidyverse) 25 | ``` 26 | 27 | # Abstract 28 | (a) Indicate the study’s design with a commonly used term in the title or the abstract 29 | (b) Provide in the abstract an informative and balanced summary of what was done and what was found 30 | 31 | # Introduction 32 | 33 | ## Background/rationale 34 | Explain the scientific background and rationale for the investigation being reported 35 | 36 | ## Objectives 37 | State specific objectives, including any prespecified hypotheses 38 | 39 | # Methods 40 | 41 | ##Study design 42 | Present key elements of study design early in the paper 43 | 44 | ## Setting 45 | Describe the setting, locations, and relevant dates, including periods of recruitment, exposure, follow-up, and data collection 46 | 47 | ## Participants 48 | (a) *Cohort study*—Give the eligibility criteria, and the sources and methods of selection of participants. Describe methods of follow-up 49 | *Case-control study*—Give the eligibility criteria, and the sources and methods of case ascertainment and control selection. Give the rationale for the choice of cases and controls 50 | *Cross-sectional study*—Give the eligibility criteria, and the sources and methods of selection of participants 51 | 52 | (b) *Cohort study*—For matched studies, give matching criteria and number of exposed and unexposed 53 | *Case-control study*—For matched studies, give matching criteria and the number of controls per case 54 | 55 | ## Variables 56 | Clearly define all outcomes, exposures, predictors, potential confounders, and effect modifiers. Give diagnostic criteria, if applicable 57 | 58 | ## Data sources/ measurement 59 | For each variable of interest, give sources of data and details of methods of assessment (measurement). Describe comparability of assessment methods if there is more than one group 60 | 61 | ## Bias 62 | Describe any efforts to address potential sources of bias 63 | 64 | ## Study size 65 | Explain how the study size was arrived at 66 | 67 | ## Quantitative variables 68 | Explain how quantitative variables were handled in the analyses. If applicable, describe which groupings were chosen and why 69 | 70 | ## Statistical methods 71 | (a) Describe all statistical methods, including those used to control for confounding 72 | (b) Describe any methods used to examine subgroups and interactions 73 | (c) Explain how missing data were addressed 74 | (d) *Cohort study*—If applicable, explain how loss to follow-up was addressed 75 | *Case-control study*—If applicable, explain how matching of cases and controls was addressed 76 | *Cross-sectional study*—If applicable, describe analytical methods taking account of sampling strategy 77 | (e) Describe any sensitivity analyses 78 | 79 | # Results 80 | 81 | ## Participants 82 | (a) Report numbers of individuals at each stage of study—eg numbers potentially eligible, examined for eligibility, confirmed eligible, included in the study, completing follow-up, and analysed 83 | (b) Give reasons for non-participation at each stage 84 | (c) Consider use of a flow diagram 85 | 86 | ## Descriptive data 87 | (a) Give characteristics of study participants (eg demographic, clinical, social) and information on exposures and potential confounders 88 | (b) Indicate number of participants with missing data for each variable of interest 89 | (c) Cohort study—Summarise follow-up time (eg, average and total amount) 90 | 91 | ## Outcome data 92 | *Cohort study*—Report numbers of outcome events or summary measures over time 93 | *Case-control study*—Report numbers in each exposure category, or summary measures of exposure 94 | *Cross-sectional study*—Report numbers of outcome events or summary measures 95 | 96 | ## Main results 97 | (a) Give unadjusted estimates and, if applicable, confounder-adjusted estimates and their precision (eg, 95% confidence interval). Make clear which confounders were adjusted for and why they were included 98 | (b) Report category boundaries when continuous variables were categorized 99 | (c) If relevant, consider translating estimates of relative risk into absolute risk for a meaningful time period 100 | 101 | ## Other analyses 102 | Report other analyses done—eg analyses of subgroups and interactions, and sensitivity analyses 103 | 104 | # Discussion 105 | 106 | ## Key results 107 | Summarise key results with reference to study objectives 108 | 109 | ## Limitations 110 | Discuss limitations of the study, taking into account sources of potential bias or imprecision. Discuss both direction and magnitude of any potential bias 111 | 112 | ## Interpretation 113 | Give a cautious overall interpretation of results considering objectives, limitations, multiplicity of analyses, results from similar studies, and other relevant evidence 114 | 115 | ## Generalisability 116 | Discuss the generalisability (external validity) of the study results 117 | 118 | \pagebreak 119 | 120 | ## References 121 | 122 | ```{r session_info, include=FALSE} 123 | save_session_info(here("progs", "session_info", "protocol")) 124 | ``` 125 | -------------------------------------------------------------------------------- /demonstration/projects/.templates/default_folder/pXXXX.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /demonstration/projects/.templates/default_folder/progs/01_protocol.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | word_document: 4 | reference_docx: styles.docx 5 | html_document: 6 | css: style.css 7 | pdf_document: 8 | default 9 | bibliography: citations.bib 10 | --- 11 | 12 | Funding: 13 | 14 | \pagebreak 15 | 16 | ```{r setup, include=FALSE} 17 | knitr::opts_chunk$set(echo = TRUE) 18 | ``` 19 | 20 | 21 | ```{r load_libraries, include=FALSE} 22 | library(projects) 23 | library(here) 24 | library(tidyverse) 25 | ``` 26 | 27 | # Abstract 28 | (a) Indicate the study’s design with a commonly used term in the title or the abstract 29 | (b) Provide in the abstract an informative and balanced summary of what was done and what was found 30 | 31 | # Introduction 32 | 33 | ## Background/rationale 34 | Explain the scientific background and rationale for the investigation being reported 35 | 36 | ## Objectives 37 | State specific objectives, including any prespecified hypotheses 38 | 39 | # Methods 40 | 41 | ##Study design 42 | Present key elements of study design early in the paper 43 | 44 | ## Setting 45 | Describe the setting, locations, and relevant dates, including periods of recruitment, exposure, follow-up, and data collection 46 | 47 | ## Participants 48 | (a) *Cohort study*—Give the eligibility criteria, and the sources and methods of selection of participants. Describe methods of follow-up 49 | *Case-control study*—Give the eligibility criteria, and the sources and methods of case ascertainment and control selection. Give the rationale for the choice of cases and controls 50 | *Cross-sectional study*—Give the eligibility criteria, and the sources and methods of selection of participants 51 | 52 | (b) *Cohort study*—For matched studies, give matching criteria and number of exposed and unexposed 53 | *Case-control study*—For matched studies, give matching criteria and the number of controls per case 54 | 55 | ## Variables 56 | Clearly define all outcomes, exposures, predictors, potential confounders, and effect modifiers. Give diagnostic criteria, if applicable 57 | 58 | ## Data sources/ measurement 59 | For each variable of interest, give sources of data and details of methods of assessment (measurement). Describe comparability of assessment methods if there is more than one group 60 | 61 | ## Bias 62 | Describe any efforts to address potential sources of bias 63 | 64 | ## Study size 65 | Explain how the study size was arrived at 66 | 67 | ## Quantitative variables 68 | Explain how quantitative variables were handled in the analyses. If applicable, describe which groupings were chosen and why 69 | 70 | ## Statistical methods 71 | (a) Describe all statistical methods, including those used to control for confounding 72 | (b) Describe any methods used to examine subgroups and interactions 73 | (c) Explain how missing data were addressed 74 | (d) *Cohort study*—If applicable, explain how loss to follow-up was addressed 75 | *Case-control study*—If applicable, explain how matching of cases and controls was addressed 76 | *Cross-sectional study*—If applicable, describe analytical methods taking account of sampling strategy 77 | (e) Describe any sensitivity analyses 78 | 79 | # Results 80 | 81 | ## Participants 82 | (a) Report numbers of individuals at each stage of study—eg numbers potentially eligible, examined for eligibility, confirmed eligible, included in the study, completing follow-up, and analysed 83 | (b) Give reasons for non-participation at each stage 84 | (c) Consider use of a flow diagram 85 | 86 | ## Descriptive data 87 | (a) Give characteristics of study participants (eg demographic, clinical, social) and information on exposures and potential confounders 88 | (b) Indicate number of participants with missing data for each variable of interest 89 | (c) Cohort study—Summarise follow-up time (eg, average and total amount) 90 | 91 | ## Outcome data 92 | *Cohort study*—Report numbers of outcome events or summary measures over time 93 | *Case-control study*—Report numbers in each exposure category, or summary measures of exposure 94 | *Cross-sectional study*—Report numbers of outcome events or summary measures 95 | 96 | ## Main results 97 | (a) Give unadjusted estimates and, if applicable, confounder-adjusted estimates and their precision (eg, 95% confidence interval). Make clear which confounders were adjusted for and why they were included 98 | (b) Report category boundaries when continuous variables were categorized 99 | (c) If relevant, consider translating estimates of relative risk into absolute risk for a meaningful time period 100 | 101 | ## Other analyses 102 | Report other analyses done—eg analyses of subgroups and interactions, and sensitivity analyses 103 | 104 | # Discussion 105 | 106 | ## Key results 107 | Summarise key results with reference to study objectives 108 | 109 | ## Limitations 110 | Discuss limitations of the study, taking into account sources of potential bias or imprecision. Discuss both direction and magnitude of any potential bias 111 | 112 | ## Interpretation 113 | Give a cautious overall interpretation of results considering objectives, limitations, multiplicity of analyses, results from similar studies, and other relevant evidence 114 | 115 | ## Generalisability 116 | Discuss the generalisability (external validity) of the study results 117 | 118 | \pagebreak 119 | 120 | ## References 121 | 122 | ```{r session_info, include=FALSE} 123 | save_session_info(here("progs", "session_info", "protocol")) 124 | ``` 125 | -------------------------------------------------------------------------------- /demonstration/projects/.templates/default_folder/progs/02_datawork.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | ```{r setup} 5 | library(projects) 6 | library(here) 7 | library(tidyverse) 8 | ``` 9 | 10 | 11 | ```{r read_raw_data} 12 | read_csv(file = ) 13 | ``` 14 | 15 | 16 | ```{r data_wrangling} 17 | 18 | ``` 19 | 20 | 21 | ```{r saver} 22 | save(..., file = here("/data/02_datawork_objects.RData")) 23 | save_session_info(here("progs", "session_info", "datawork")) 24 | ``` 25 | -------------------------------------------------------------------------------- /demonstration/projects/.templates/default_folder/progs/03_analysis.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | ```{r setup} 5 | library(projects) 6 | library(here) 7 | library(tidyverse) 8 | ``` 9 | 10 | 11 | ```{r load_02_datawork_data} 12 | load(file = here("/data/02_datawork_objects.RData")) 13 | ``` 14 | 15 | 16 | ```{r analysis} 17 | 18 | ``` 19 | 20 | 21 | ```{r saver} 22 | save(..., file = here("/data/03_analysis_objects.RData")) 23 | save_session_info(here("progs", "session_info", "analysis")) 24 | ``` 25 | -------------------------------------------------------------------------------- /demonstration/projects/.templates/default_folder/progs/04_report.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | word_document: 4 | reference_docx: styles.docx 5 | html_document: 6 | css: style.css 7 | pdf_document: 8 | default 9 | bibliography: citations.bib 10 | --- 11 | 12 | Funding: 13 | 14 | ```{r setup, include=FALSE} 15 | knitr::opts_chunk$set(echo = TRUE) 16 | ``` 17 | 18 | ```{r load_libraries, include=FALSE} 19 | library(projects) 20 | library(here) 21 | library(tidyverse) 22 | ``` 23 | 24 | ```{r load_03_analysis_data, include=FALSE} 25 | load(file = here("/data/03_analysis_objects.RData")) 26 | ``` 27 | 28 | # Abstract 29 | 30 | xxxxxxxx 31 | 32 | \pagebreak 33 | 34 | # Introduction 35 | 36 | xxxxxxxx 37 | 38 | # Methods 39 | 40 | xxxxxxxx 41 | 42 | # Results 43 | 44 | xxxxxxxx 45 | 46 | # Discussion 47 | 48 | xxxxxxxx 49 | 50 | \pagebreak 51 | 52 | ## References 53 | 54 | ```{r session_info, include=FALSE} 55 | save_session_info(here("progs", "session_info", "report")) 56 | ``` 57 | 58 | -------------------------------------------------------------------------------- /demonstration/projects/.templates/default_folder/progs/citations.bib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/.templates/default_folder/progs/citations.bib -------------------------------------------------------------------------------- /demonstration/projects/.templates/default_folder/progs/style.css: -------------------------------------------------------------------------------- 1 | body{ /* Normal */ 2 | font-size: 11px; 3 | } 4 | td { /* Table */ 5 | font-size: 11px; 6 | } 7 | h1.title { 8 | font-size: 24px; 9 | color: DarkRed; 10 | } 11 | h1 { /* Header 1 */ 12 | font-size: 14px; 13 | font-weight: bold; 14 | color: DarkRed; 15 | } 16 | h2 { /* Header 2 */ 17 | font-size: 12px; 18 | font-weight: bold; 19 | font-style: italic; 20 | color: Black; 21 | } 22 | h3 { /* Header 3 */ 23 | font-size: 11px; 24 | color: Black; 25 | } 26 | code.r{ /* Code block */ 27 | font-size: 10px; 28 | } 29 | pre { /* Code block - determines code spacing between lines */ 30 | font-size: 10px; 31 | } 32 | -------------------------------------------------------------------------------- /demonstration/projects/.templates/default_folder/progs/styles.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/.templates/default_folder/progs/styles.docx -------------------------------------------------------------------------------- /demonstration/projects/p0012/data/02_datawork_objects.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/p0012/data/02_datawork_objects.RData -------------------------------------------------------------------------------- /demonstration/projects/p0012/data/03_analysis_objects.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/p0012/data/03_analysis_objects.RData -------------------------------------------------------------------------------- /demonstration/projects/p0012/data_raw/toy-dataset.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/p0012/data_raw/toy-dataset.zip -------------------------------------------------------------------------------- /demonstration/projects/p0012/figures/income_by_gender_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/p0012/figures/income_by_gender_plot.png -------------------------------------------------------------------------------- /demonstration/projects/p0012/p0012.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/01_protocol.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Achieving Cold Fusion" 3 | author: 4 | - Scott Bug, PhD;^1,2^\* Chien-Shiung Wu, PhD;^2,3^ Leonardo da Vinci; George Washington Carver, MS;^1,2,3^ and Marie Curie^3^ 5 | - ^1^ Impossibles Investigation Team, Creekshirebrook Academy of Thinks, Let Gade 27182, 1566 Copenhagen, Denmark 6 | - ^2^ Department of Physics, University of North Science, 314 Newton Blvd, Springfield CT 06003 7 | - ^3^ Statistical Consulting Unit, Creekshirebrook Academy of Thinks, 196 Normal Ave, Columbus, OH 8 | - \* Corresponding author 9 | - Let Gade 27182, 1566 Copenhagen, Denmark 10 | - 965-555-5556 11 | - scottbug@impossible.net 12 | output: 13 | word_document: 14 | reference_docx: styles.docx 15 | html_document: 16 | css: style.css 17 | pdf_document: 18 | default 19 | bibliography: citations.bib 20 | --- 21 | 22 | Funding: 23 | 24 | \pagebreak 25 | 26 | ```{r setup, include=FALSE} 27 | knitr::opts_chunk$set(echo = TRUE) 28 | ``` 29 | 30 | 31 | ```{r load_libraries, include=FALSE} 32 | library(skimr) 33 | library(projects) 34 | library(here) 35 | library(tidyverse) 36 | ``` 37 | 38 | # Abstract 39 | 40 | A generalized linear model determining who is ill based on age, income, and whether or not someone lives on the east coast is ineffective at the 0.1 significance level. 41 | 42 | # Introduction 43 | 44 | It is common knowledge that sometimes people fall ill, and while it seems difficult to predict who will become ill, perhaps it is an attainable goal to determine who is already ill at any given moment. 45 | 46 | ## Background/rationale 47 | 48 | Most people seem not to like being ill, [@wiki] and science has proven that many diseases are communicable. Knowing who is ill may help to decrease transmission of communicable disease. 49 | 50 | ## Objectives 51 | 52 | We hypothesize that characteristics of an individual will help to inform who is ill, and we hope to accomplish this using statistical techniques. 53 | 54 | # Methods 55 | 56 | ##Study design 57 | 58 | We will perform a generalized linear model describing who is ill based on certain demographic information. We will use R statistical software, version 3.5.0. [@R] 59 | 60 | ## Setting 61 | 62 | Americentric boundaries on this study lead us to only be interested in people living in the US. Laziness causes us to disregard the period during which these data were collected. 63 | 64 | ## Participants 65 | (a) This is a cross-sectional study of adults living in the United States. Subjects must have a non-negative income. 66 | 67 | ## Variables 68 | The outcome variable is binary, indicating whether or not the person is ill. The explanatory variables will be gender, income in dollars, age, and city of residence. We will test collinearity of some of these explanatory variables before developingn our final model. 69 | 70 | ## Data sources/ measurement 71 | The study data comprises 149,999 adults between 25 and 65 years of age all living in the United States, taken from a data set of 150,000 such individuals. [@kaggle] 72 | 73 | ## Bias 74 | This data set only contains individuals of age 25 to 65, so all other individuals will be excluded; any resulting model will likely not be useful for people outside this age range. 75 | 76 | ## Study size 77 | One individual will be excluded because their listed income is under $0. 78 | 79 | ## Quantitative variables 80 | All quantitative variables will be treated at face value; none were categorized nor transformed. 81 | 82 | ## Statistical methods 83 | There are no missing data, fortunately. We will utilize a generalized linear model. 84 | 85 | ## Descriptive data 86 | 87 | Here are descriptive statistics of the raw data set: 88 | 89 | ```{r skim, echo=FALSE} 90 | skim(read_csv(here("data_raw", "toy_dataset.csv"))) 91 | ``` 92 | 93 | ## Limitations 94 | The primarly limitation of this study is its use of a toy data set. These data are all fictional. Also, even if they were not, this model is overly simplistic. Nonetheless, we will proceed. 95 | 96 | \pagebreak 97 | 98 | ## References 99 | 100 | ```{r session_info, include=FALSE} 101 | save_session_info(here("progs", "session_info", "protocol")) 102 | ``` 103 | 104 | -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/01_protocol.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/p0012/progs/01_protocol.docx -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/02_datawork.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "p0012 datawork" 3 | --- 4 | 5 | ```{r setup} 6 | library(skimr) 7 | library(projects) 8 | library(here) 9 | library(tidyverse) 10 | ``` 11 | 12 | 13 | ```{r read_raw_data} 14 | raw_people <- read_csv(here("data_raw", "toy_dataset.csv")) 15 | skim(raw_people) 16 | levels(as.factor(raw_people$City)) 17 | ``` 18 | 19 | 20 | ```{r data_wrangling} 21 | clean_people <- 22 | raw_people %>% 23 | rename_all(tolower) %>% 24 | filter(income > 0) %>% 25 | mutate( 26 | female = as.integer(gender == "Female"), 27 | illness = as.integer(illness == "Yes"), 28 | east_coast = 29 | as.integer(city %in% c("New York City", "Boston", "Washington D.C.")) 30 | ) %>% 31 | select( 32 | gender, 33 | female, 34 | age_years = age, 35 | income_dollars = income, 36 | east_coast, 37 | illness 38 | ) 39 | 40 | clean_people 41 | ``` 42 | 43 | 44 | ```{r saver} 45 | save(clean_people, file = here("data", "02_datawork_objects.RData")) 46 | save_session_info(here("progs", "session_info", "datawork")) 47 | ``` 48 | -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/03_analysis.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "p0012 analysis" 3 | --- 4 | 5 | ```{r setup} 6 | library(projects) 7 | library(here) 8 | library(tidyverse) 9 | ``` 10 | 11 | 12 | ```{r load_02_datawork_data} 13 | load(file = here("data", "02_datawork_objects.RData")) 14 | ``` 15 | 16 | 17 | ```{r analysis} 18 | income_by_gender_plot <- 19 | ggplot(clean_people) + 20 | geom_density(aes(income_dollars)) + 21 | facet_wrap(vars(gender), nrow = 2) + 22 | theme_minimal() 23 | 24 | ggsave( 25 | here("figures", "income_by_gender_plot.png"), 26 | plot = income_by_gender_plot, 27 | dpi = "retina" 28 | ) 29 | ``` 30 | 31 | ```{r illness_model} 32 | model1 <- 33 | glm( 34 | illness ~ age_years + income_dollars + east_coast, 35 | data = clean_people 36 | ) 37 | 38 | summary(model1) 39 | ``` 40 | 41 | 42 | ```{r saver} 43 | save( 44 | income_by_gender_plot, 45 | model1, 46 | file = here("/data/03_analysis_objects.RData") 47 | ) 48 | save_session_info(here("progs", "session_info", "analysis")) 49 | ``` 50 | -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/04_report.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Achieving Cold Fusion" 3 | author: 4 | - Scott Bug, PhD;^1,2^\* Chien-Shiung Wu, PhD;^2,3^ Leonardo da Vinci; George Washington Carver, MS;^1,2,3^ and Marie Curie^3^ 5 | - ^1^ Impossibles Investigation Team, Creekshirebrook Academy of Thinks, Let Gade 27182, 1566 Copenhagen, Denmark 6 | - ^2^ Department of Physics, University of North Science, 314 Newton Blvd, Springfield CT 06003 7 | - ^3^ Statistical Consulting Unit, Creekshirebrook Academy of Thinks, 196 Normal Ave, Columbus, OH 8 | - \* Corresponding author 9 | - Let Gade 27182, 1566 Copenhagen, Denmark 10 | - 965-555-5556 11 | - scottbug@impossible.net 12 | output: 13 | html_document: 14 | css: style.css 15 | word_document: 16 | reference_docx: styles.docx 17 | pdf_document: 18 | default 19 | bibliography: citations.bib 20 | --- 21 | 22 | ```{r setup, include=FALSE} 23 | knitr::opts_chunk$set(echo = TRUE) 24 | ``` 25 | 26 | ```{r load_libraries, include=FALSE} 27 | library(projects) 28 | library(here) 29 | library(tidyverse) 30 | ``` 31 | 32 | ```{r load_03_analysis_data, include=FALSE} 33 | load(file = here("/data/03_analysis_objects.RData")) 34 | ``` 35 | 36 | # Abstract 37 | 38 | A generalized linear model determining who is ill based on age, income, and whether or not someone lives on the east coast is ineffective at the 0.1 significance level. 39 | 40 | \pagebreak 41 | 42 | # Introduction 43 | 44 | Studies have shown that people are ill sometimes. [@wiki] This includes women, men, young people, and older people throughout the UnitedStates. However, research fails to explain exactly which people are ill at any given moment. Statistical modeling may be able to shed light on this subject. 45 | 46 | # Methods 47 | 48 | A generalized linear model was developed in order to understand who was ill among a sample of adults living in the United States. Explanatory variables include annual income in dollars, truncated age in years, and whether or not individuals lived in an east coast city. The study sample contained 149,999 men and women between the ages of 25 and 65 living in the US, taken from a dataset of 150,000. [@kaggle] The excluded individual had a listed annual income under $0. 49 | 50 | Before model creation, the relationship between gender and annual income was examined graphically in order to inspect collinearity. 51 | 52 | The model was created using R statistical software version 3.5.0. [@R] 53 | 54 | ```{r ibgp, echo=FALSE} 55 | income_by_gender_plot 56 | ``` 57 | 58 | The distribution of men's income is higher overall than women's income, so gender was excluded from the model. 59 | 60 | # Results 61 | 62 | None of the explanatory variables in the generalized linear model were statistically significant at the 0.1 significance level: 63 | 64 | ```{r model, echo=FALSE} 65 | summary(model1) 66 | ``` 67 | 68 | # Discussion 69 | 70 | A generalized linear model explaining who is ill based on age, income, and residence in an east coast city is insufficient. More research is needed in order to determine the factors that explain who is ill. 71 | 72 | The primarly limitation of this study is its use of a toy data set. These data are all fictional. Also, even if they were not, this model is overly simplistic. 73 | 74 | \pagebreak 75 | 76 | ## References 77 | 78 | ```{r session_info, include=FALSE} 79 | save_session_info(here("progs", "session_info", "report")) 80 | ``` 81 | 82 | -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/citations.bib: -------------------------------------------------------------------------------- 1 | 2 | @Manual{R, 3 | title = {R: A Language and Environment for Statistical Computing}, 4 | author = {{R Core Team}}, 5 | organization = {R Foundation for Statistical Computing}, 6 | address = {Vienna, Austria}, 7 | year = {2018}, 8 | url = {https://www.R-project.org/}, 9 | } 10 | 11 | 12 | @misc{kaggle, 13 | title = {Toy Dataset}, 14 | author = {Carlos Lepelaars}, 15 | year = {2018}, 16 | howpublished = {\url{https://www.kaggle.com/carlolepelaars/toy-dataset}}, 17 | note = "[Online; accessed 22-May-2019]" 18 | } 19 | 20 | 21 | @misc{wiki, 22 | author = "Wikipedia", 23 | title = "{Main Page} --- {W}ikipedia{,} The Free Encyclopedia", 24 | year = "2019", 25 | howpublished = {\url{http://en.wikipedia.org/w/index.php?title=Main\%20Page&oldid=889268954}}, 26 | note = "[Online; accessed 23-May-2019]" 27 | } -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/session_info/analysis/session_info_20190903_15꞉42꞉18_EDT.txt: -------------------------------------------------------------------------------- 1 | Run time: 2019-09-03 15:42:18 EDT 2 | 3 | ─ Session info ────────────────────────────────────────────────────────── 4 | setting value 5 | version R version 3.5.0 (2018-04-23) 6 | os CentOS Linux 7 (Core) 7 | system x86_64, linux-gnu 8 | ui X11 9 | language (EN) 10 | collate en_US.UTF-8 11 | ctype en_US.UTF-8 12 | tz America/New_York 13 | date 2019-09-03 14 | 15 | ─ Packages ────────────────────────────────────────────────────────────── 16 | package * version date lib source 17 | assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.5.0) 18 | backports 1.1.4 2019-04-10 [1] CRAN (R 3.5.0) 19 | broom 0.4.4 2018-03-29 [2] CRAN (R 3.5.0) 20 | cellranger 1.1.0 2016-07-27 [2] CRAN (R 3.5.0) 21 | cli 1.1.0 2019-03-19 [1] CRAN (R 3.5.0) 22 | colorspace 1.4-0 2019-01-13 [1] CRAN (R 3.5.0) 23 | crayon 1.3.4 2017-09-16 [2] CRAN (R 3.5.0) 24 | digest 0.6.20 2019-07-04 [1] CRAN (R 3.5.0) 25 | dplyr * 0.8.3 2019-07-04 [1] CRAN (R 3.5.0) 26 | evaluate 0.13 2019-02-12 [1] CRAN (R 3.5.0) 27 | forcats * 0.3.0 2018-02-19 [2] CRAN (R 3.5.0) 28 | foreign 0.8-70 2017-11-28 [2] CRAN (R 3.5.0) 29 | fs 1.3.1 2019-05-06 [1] CRAN (R 3.5.0) 30 | ggplot2 * 3.2.0 2019-06-16 [1] CRAN (R 3.5.0) 31 | glue 1.3.1 2019-03-12 [1] CRAN (R 3.5.0) 32 | gtable 0.2.0 2016-02-26 [2] CRAN (R 3.5.0) 33 | haven 2.1.0 2019-02-19 [1] CRAN (R 3.5.0) 34 | here * 0.1 2017-05-28 [1] CRAN (R 3.5.0) 35 | hms 0.4.2 2018-03-10 [2] CRAN (R 3.5.0) 36 | htmltools 0.3.6 2017-04-28 [2] CRAN (R 3.5.0) 37 | httr 1.4.0 2018-12-11 [1] CRAN (R 3.5.0) 38 | jsonlite 1.6 2018-12-07 [1] CRAN (R 3.5.0) 39 | knitr 1.22 2019-03-08 [1] CRAN (R 3.5.0) 40 | labeling 0.3 2014-08-23 [2] CRAN (R 3.5.0) 41 | lattice 0.20-35 2017-03-25 [2] CRAN (R 3.5.0) 42 | lazyeval 0.2.1 2017-10-29 [2] CRAN (R 3.5.0) 43 | lifecycle 0.1.0 2019-08-01 [1] CRAN (R 3.5.0) 44 | lubridate 1.7.4 2018-04-11 [2] CRAN (R 3.5.0) 45 | magrittr 1.5 2014-11-22 [1] CRAN (R 3.5.0) 46 | mnormt 1.5-5 2016-10-15 [2] CRAN (R 3.5.0) 47 | modelr 0.1.4 2019-02-18 [1] CRAN (R 3.5.0) 48 | munsell 0.5.0 2018-06-12 [1] CRAN (R 3.5.0) 49 | nlme 3.1-137 2018-04-07 [2] CRAN (R 3.5.0) 50 | pillar 1.4.2 2019-06-29 [1] CRAN (R 3.5.0) 51 | pkgconfig 2.0.2 2018-08-16 [1] CRAN (R 3.5.0) 52 | plyr 1.8.4 2016-06-08 [2] CRAN (R 3.5.0) 53 | projects * 1.3.0 2019-09-03 [1] local 54 | psych 1.8.12 2019-01-12 [1] CRAN (R 3.5.0) 55 | purrr * 0.3.2 2019-03-15 [1] CRAN (R 3.5.0) 56 | R6 2.4.0 2019-02-14 [1] CRAN (R 3.5.0) 57 | Rcpp 1.0.2 2019-07-25 [1] CRAN (R 3.5.0) 58 | readr * 1.3.1 2018-12-21 [1] CRAN (R 3.5.0) 59 | readxl 1.1.0 2018-04-20 [2] CRAN (R 3.5.0) 60 | reshape2 1.4.3 2017-12-11 [2] CRAN (R 3.5.0) 61 | rlang 0.4.0 2019-06-25 [1] CRAN (R 3.5.0) 62 | rmarkdown 1.12 2019-03-14 [1] CRAN (R 3.5.0) 63 | rprojroot 1.3-2 2018-01-03 [2] CRAN (R 3.5.0) 64 | rstudioapi 0.7 2017-09-07 [2] CRAN (R 3.5.0) 65 | rvest 0.3.2 2016-06-17 [2] CRAN (R 3.5.0) 66 | scales 1.0.0 2018-08-09 [1] CRAN (R 3.5.0) 67 | sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.5.0) 68 | stringi 1.4.3 2019-03-12 [1] CRAN (R 3.5.0) 69 | stringr * 1.4.0 2019-02-10 [1] CRAN (R 3.5.0) 70 | tibble * 2.1.3 2019-06-06 [1] CRAN (R 3.5.0) 71 | tidyr * 0.8.99.9000 2019-08-23 [1] Github (tidyverse/tidyr@a3431e3) 72 | tidyselect 0.2.5 2018-10-11 [1] CRAN (R 3.5.0) 73 | tidyverse * 1.2.1 2017-11-14 [2] CRAN (R 3.5.0) 74 | vctrs 0.2.0 2019-07-05 [1] CRAN (R 3.5.0) 75 | withr 2.1.2 2018-03-15 [2] CRAN (R 3.5.0) 76 | xfun 0.7 2019-05-14 [1] CRAN (R 3.5.0) 77 | xml2 1.2.0 2018-01-24 [2] CRAN (R 3.5.0) 78 | yaml 2.2.0 2018-07-25 [1] CRAN (R 3.5.0) 79 | zeallot 0.1.0 2018-01-28 [1] CRAN (R 3.5.0) 80 | 81 | [1] /home/kriegen/R/x86_64-pc-linux-gnu-library/3.5 82 | [2] /opt/R-3.5.0/lib64/R/library 83 | -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/session_info/datawork/session_info_20190903_15꞉41꞉21_EDT.txt: -------------------------------------------------------------------------------- 1 | Run time: 2019-09-03 15:41:21 EDT 2 | 3 | ─ Session info ────────────────────────────────────────────────────────── 4 | setting value 5 | version R version 3.5.0 (2018-04-23) 6 | os CentOS Linux 7 (Core) 7 | system x86_64, linux-gnu 8 | ui X11 9 | language (EN) 10 | collate en_US.UTF-8 11 | ctype en_US.UTF-8 12 | tz America/New_York 13 | date 2019-09-03 14 | 15 | ─ Packages ────────────────────────────────────────────────────────────── 16 | package * version date lib source 17 | assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.5.0) 18 | backports 1.1.4 2019-04-10 [1] CRAN (R 3.5.0) 19 | broom 0.4.4 2018-03-29 [2] CRAN (R 3.5.0) 20 | cellranger 1.1.0 2016-07-27 [2] CRAN (R 3.5.0) 21 | cli 1.1.0 2019-03-19 [1] CRAN (R 3.5.0) 22 | colorspace 1.4-0 2019-01-13 [1] CRAN (R 3.5.0) 23 | crayon 1.3.4 2017-09-16 [2] CRAN (R 3.5.0) 24 | digest 0.6.20 2019-07-04 [1] CRAN (R 3.5.0) 25 | dplyr * 0.8.3 2019-07-04 [1] CRAN (R 3.5.0) 26 | evaluate 0.13 2019-02-12 [1] CRAN (R 3.5.0) 27 | fansi 0.4.0 2018-10-05 [1] CRAN (R 3.5.0) 28 | forcats * 0.3.0 2018-02-19 [2] CRAN (R 3.5.0) 29 | foreign 0.8-70 2017-11-28 [2] CRAN (R 3.5.0) 30 | fs 1.3.1 2019-05-06 [1] CRAN (R 3.5.0) 31 | ggplot2 * 3.2.0 2019-06-16 [1] CRAN (R 3.5.0) 32 | glue 1.3.1 2019-03-12 [1] CRAN (R 3.5.0) 33 | gtable 0.2.0 2016-02-26 [2] CRAN (R 3.5.0) 34 | haven 2.1.0 2019-02-19 [1] CRAN (R 3.5.0) 35 | here * 0.1 2017-05-28 [1] CRAN (R 3.5.0) 36 | hms 0.4.2 2018-03-10 [2] CRAN (R 3.5.0) 37 | htmltools 0.3.6 2017-04-28 [2] CRAN (R 3.5.0) 38 | httr 1.4.0 2018-12-11 [1] CRAN (R 3.5.0) 39 | jsonlite 1.6 2018-12-07 [1] CRAN (R 3.5.0) 40 | knitr 1.22 2019-03-08 [1] CRAN (R 3.5.0) 41 | lattice 0.20-35 2017-03-25 [2] CRAN (R 3.5.0) 42 | lazyeval 0.2.1 2017-10-29 [2] CRAN (R 3.5.0) 43 | lifecycle 0.1.0 2019-08-01 [1] CRAN (R 3.5.0) 44 | lubridate 1.7.4 2018-04-11 [2] CRAN (R 3.5.0) 45 | magrittr 1.5 2014-11-22 [1] CRAN (R 3.5.0) 46 | mnormt 1.5-5 2016-10-15 [2] CRAN (R 3.5.0) 47 | modelr 0.1.4 2019-02-18 [1] CRAN (R 3.5.0) 48 | munsell 0.5.0 2018-06-12 [1] CRAN (R 3.5.0) 49 | nlme 3.1-137 2018-04-07 [2] CRAN (R 3.5.0) 50 | pillar 1.4.2 2019-06-29 [1] CRAN (R 3.5.0) 51 | pkgconfig 2.0.2 2018-08-16 [1] CRAN (R 3.5.0) 52 | plyr 1.8.4 2016-06-08 [2] CRAN (R 3.5.0) 53 | projects * 1.3.0 2019-09-03 [1] local 54 | psych 1.8.12 2019-01-12 [1] CRAN (R 3.5.0) 55 | purrr * 0.3.2 2019-03-15 [1] CRAN (R 3.5.0) 56 | R6 2.4.0 2019-02-14 [1] CRAN (R 3.5.0) 57 | Rcpp 1.0.2 2019-07-25 [1] CRAN (R 3.5.0) 58 | readr * 1.3.1 2018-12-21 [1] CRAN (R 3.5.0) 59 | readxl 1.1.0 2018-04-20 [2] CRAN (R 3.5.0) 60 | reshape2 1.4.3 2017-12-11 [2] CRAN (R 3.5.0) 61 | rlang 0.4.0 2019-06-25 [1] CRAN (R 3.5.0) 62 | rmarkdown 1.12 2019-03-14 [1] CRAN (R 3.5.0) 63 | rprojroot 1.3-2 2018-01-03 [2] CRAN (R 3.5.0) 64 | rstudioapi 0.7 2017-09-07 [2] CRAN (R 3.5.0) 65 | rvest 0.3.2 2016-06-17 [2] CRAN (R 3.5.0) 66 | scales 1.0.0 2018-08-09 [1] CRAN (R 3.5.0) 67 | sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.5.0) 68 | skimr * 1.0.4 2019-01-13 [1] CRAN (R 3.5.0) 69 | stringi 1.4.3 2019-03-12 [1] CRAN (R 3.5.0) 70 | stringr * 1.4.0 2019-02-10 [1] CRAN (R 3.5.0) 71 | tibble * 2.1.3 2019-06-06 [1] CRAN (R 3.5.0) 72 | tidyr * 0.8.99.9000 2019-08-23 [1] Github (tidyverse/tidyr@a3431e3) 73 | tidyselect 0.2.5 2018-10-11 [1] CRAN (R 3.5.0) 74 | tidyverse * 1.2.1 2017-11-14 [2] CRAN (R 3.5.0) 75 | utf8 1.1.4 2018-05-24 [1] CRAN (R 3.5.0) 76 | vctrs 0.2.0 2019-07-05 [1] CRAN (R 3.5.0) 77 | withr 2.1.2 2018-03-15 [2] CRAN (R 3.5.0) 78 | xfun 0.7 2019-05-14 [1] CRAN (R 3.5.0) 79 | xml2 1.2.0 2018-01-24 [2] CRAN (R 3.5.0) 80 | yaml 2.2.0 2018-07-25 [1] CRAN (R 3.5.0) 81 | zeallot 0.1.0 2018-01-28 [1] CRAN (R 3.5.0) 82 | 83 | [1] /home/kriegen/R/x86_64-pc-linux-gnu-library/3.5 84 | [2] /opt/R-3.5.0/lib64/R/library 85 | -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/session_info/protocol/session_info_20190903_15꞉40꞉10_EDT.txt: -------------------------------------------------------------------------------- 1 | Run time: 2019-09-03 15:40:10 EDT 2 | 3 | ─ Session info ────────────────────────────────────────────────────────── 4 | setting value 5 | version R version 3.5.0 (2018-04-23) 6 | os CentOS Linux 7 (Core) 7 | system x86_64, linux-gnu 8 | ui X11 9 | language (EN) 10 | collate en_US.UTF-8 11 | ctype en_US.UTF-8 12 | tz America/New_York 13 | date 2019-09-03 14 | 15 | ─ Packages ────────────────────────────────────────────────────────────── 16 | package * version date lib source 17 | assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.5.0) 18 | backports 1.1.4 2019-04-10 [1] CRAN (R 3.5.0) 19 | broom 0.4.4 2018-03-29 [2] CRAN (R 3.5.0) 20 | cellranger 1.1.0 2016-07-27 [2] CRAN (R 3.5.0) 21 | cli 1.1.0 2019-03-19 [1] CRAN (R 3.5.0) 22 | colorspace 1.4-0 2019-01-13 [1] CRAN (R 3.5.0) 23 | crayon 1.3.4 2017-09-16 [2] CRAN (R 3.5.0) 24 | digest 0.6.20 2019-07-04 [1] CRAN (R 3.5.0) 25 | dplyr * 0.8.3 2019-07-04 [1] CRAN (R 3.5.0) 26 | evaluate 0.13 2019-02-12 [1] CRAN (R 3.5.0) 27 | forcats * 0.3.0 2018-02-19 [2] CRAN (R 3.5.0) 28 | foreign 0.8-70 2017-11-28 [2] CRAN (R 3.5.0) 29 | fs 1.3.1 2019-05-06 [1] CRAN (R 3.5.0) 30 | ggplot2 * 3.2.0 2019-06-16 [1] CRAN (R 3.5.0) 31 | glue 1.3.1 2019-03-12 [1] CRAN (R 3.5.0) 32 | gtable 0.2.0 2016-02-26 [2] CRAN (R 3.5.0) 33 | haven 2.1.0 2019-02-19 [1] CRAN (R 3.5.0) 34 | here * 0.1 2017-05-28 [1] CRAN (R 3.5.0) 35 | hms 0.4.2 2018-03-10 [2] CRAN (R 3.5.0) 36 | htmltools 0.3.6 2017-04-28 [2] CRAN (R 3.5.0) 37 | httr 1.4.0 2018-12-11 [1] CRAN (R 3.5.0) 38 | jsonlite 1.6 2018-12-07 [1] CRAN (R 3.5.0) 39 | knitr 1.22 2019-03-08 [1] CRAN (R 3.5.0) 40 | lattice 0.20-35 2017-03-25 [2] CRAN (R 3.5.0) 41 | lazyeval 0.2.1 2017-10-29 [2] CRAN (R 3.5.0) 42 | lifecycle 0.1.0 2019-08-01 [1] CRAN (R 3.5.0) 43 | lubridate 1.7.4 2018-04-11 [2] CRAN (R 3.5.0) 44 | magrittr 1.5 2014-11-22 [1] CRAN (R 3.5.0) 45 | mnormt 1.5-5 2016-10-15 [2] CRAN (R 3.5.0) 46 | modelr 0.1.4 2019-02-18 [1] CRAN (R 3.5.0) 47 | munsell 0.5.0 2018-06-12 [1] CRAN (R 3.5.0) 48 | nlme 3.1-137 2018-04-07 [2] CRAN (R 3.5.0) 49 | pillar 1.4.2 2019-06-29 [1] CRAN (R 3.5.0) 50 | pkgconfig 2.0.2 2018-08-16 [1] CRAN (R 3.5.0) 51 | plyr 1.8.4 2016-06-08 [2] CRAN (R 3.5.0) 52 | projects * 1.3.0 2019-09-03 [1] local 53 | psych 1.8.12 2019-01-12 [1] CRAN (R 3.5.0) 54 | purrr * 0.3.2 2019-03-15 [1] CRAN (R 3.5.0) 55 | R6 2.4.0 2019-02-14 [1] CRAN (R 3.5.0) 56 | Rcpp 1.0.2 2019-07-25 [1] CRAN (R 3.5.0) 57 | readr * 1.3.1 2018-12-21 [1] CRAN (R 3.5.0) 58 | readxl 1.1.0 2018-04-20 [2] CRAN (R 3.5.0) 59 | reshape2 1.4.3 2017-12-11 [2] CRAN (R 3.5.0) 60 | rlang 0.4.0 2019-06-25 [1] CRAN (R 3.5.0) 61 | rmarkdown 1.12 2019-03-14 [1] CRAN (R 3.5.0) 62 | rprojroot 1.3-2 2018-01-03 [2] CRAN (R 3.5.0) 63 | rstudioapi 0.7 2017-09-07 [2] CRAN (R 3.5.0) 64 | rvest 0.3.2 2016-06-17 [2] CRAN (R 3.5.0) 65 | scales 1.0.0 2018-08-09 [1] CRAN (R 3.5.0) 66 | sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.5.0) 67 | skimr * 1.0.4 2019-01-13 [1] CRAN (R 3.5.0) 68 | stringi 1.4.3 2019-03-12 [1] CRAN (R 3.5.0) 69 | stringr * 1.4.0 2019-02-10 [1] CRAN (R 3.5.0) 70 | tibble * 2.1.3 2019-06-06 [1] CRAN (R 3.5.0) 71 | tidyr * 0.8.99.9000 2019-08-23 [1] Github (tidyverse/tidyr@a3431e3) 72 | tidyselect 0.2.5 2018-10-11 [1] CRAN (R 3.5.0) 73 | tidyverse * 1.2.1 2017-11-14 [2] CRAN (R 3.5.0) 74 | vctrs 0.2.0 2019-07-05 [1] CRAN (R 3.5.0) 75 | withr 2.1.2 2018-03-15 [2] CRAN (R 3.5.0) 76 | xfun 0.7 2019-05-14 [1] CRAN (R 3.5.0) 77 | xml2 1.2.0 2018-01-24 [2] CRAN (R 3.5.0) 78 | yaml 2.2.0 2018-07-25 [1] CRAN (R 3.5.0) 79 | zeallot 0.1.0 2018-01-28 [1] CRAN (R 3.5.0) 80 | 81 | [1] /home/kriegen/R/x86_64-pc-linux-gnu-library/3.5 82 | [2] /opt/R-3.5.0/lib64/R/library 83 | -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/session_info/report/session_info_20190903_15꞉43꞉17_EDT.txt: -------------------------------------------------------------------------------- 1 | Run time: 2019-09-03 15:43:17 EDT 2 | 3 | ─ Session info ────────────────────────────────────────────────────────── 4 | setting value 5 | version R version 3.5.0 (2018-04-23) 6 | os CentOS Linux 7 (Core) 7 | system x86_64, linux-gnu 8 | ui X11 9 | language (EN) 10 | collate en_US.UTF-8 11 | ctype en_US.UTF-8 12 | tz America/New_York 13 | date 2019-09-03 14 | 15 | ─ Packages ────────────────────────────────────────────────────────────── 16 | package * version date lib source 17 | assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.5.0) 18 | backports 1.1.4 2019-04-10 [1] CRAN (R 3.5.0) 19 | broom 0.4.4 2018-03-29 [2] CRAN (R 3.5.0) 20 | cellranger 1.1.0 2016-07-27 [2] CRAN (R 3.5.0) 21 | cli 1.1.0 2019-03-19 [1] CRAN (R 3.5.0) 22 | colorspace 1.4-0 2019-01-13 [1] CRAN (R 3.5.0) 23 | crayon 1.3.4 2017-09-16 [2] CRAN (R 3.5.0) 24 | digest 0.6.20 2019-07-04 [1] CRAN (R 3.5.0) 25 | dplyr * 0.8.3 2019-07-04 [1] CRAN (R 3.5.0) 26 | evaluate 0.13 2019-02-12 [1] CRAN (R 3.5.0) 27 | forcats * 0.3.0 2018-02-19 [2] CRAN (R 3.5.0) 28 | foreign 0.8-70 2017-11-28 [2] CRAN (R 3.5.0) 29 | fs 1.3.1 2019-05-06 [1] CRAN (R 3.5.0) 30 | ggplot2 * 3.2.0 2019-06-16 [1] CRAN (R 3.5.0) 31 | glue 1.3.1 2019-03-12 [1] CRAN (R 3.5.0) 32 | gtable 0.2.0 2016-02-26 [2] CRAN (R 3.5.0) 33 | haven 2.1.0 2019-02-19 [1] CRAN (R 3.5.0) 34 | here * 0.1 2017-05-28 [1] CRAN (R 3.5.0) 35 | hms 0.4.2 2018-03-10 [2] CRAN (R 3.5.0) 36 | htmltools 0.3.6 2017-04-28 [2] CRAN (R 3.5.0) 37 | httr 1.4.0 2018-12-11 [1] CRAN (R 3.5.0) 38 | jsonlite 1.6 2018-12-07 [1] CRAN (R 3.5.0) 39 | knitr 1.22 2019-03-08 [1] CRAN (R 3.5.0) 40 | labeling 0.3 2014-08-23 [2] CRAN (R 3.5.0) 41 | lattice 0.20-35 2017-03-25 [2] CRAN (R 3.5.0) 42 | lazyeval 0.2.1 2017-10-29 [2] CRAN (R 3.5.0) 43 | lifecycle 0.1.0 2019-08-01 [1] CRAN (R 3.5.0) 44 | lubridate 1.7.4 2018-04-11 [2] CRAN (R 3.5.0) 45 | magrittr 1.5 2014-11-22 [1] CRAN (R 3.5.0) 46 | mnormt 1.5-5 2016-10-15 [2] CRAN (R 3.5.0) 47 | modelr 0.1.4 2019-02-18 [1] CRAN (R 3.5.0) 48 | munsell 0.5.0 2018-06-12 [1] CRAN (R 3.5.0) 49 | nlme 3.1-137 2018-04-07 [2] CRAN (R 3.5.0) 50 | pillar 1.4.2 2019-06-29 [1] CRAN (R 3.5.0) 51 | pkgconfig 2.0.2 2018-08-16 [1] CRAN (R 3.5.0) 52 | plyr 1.8.4 2016-06-08 [2] CRAN (R 3.5.0) 53 | projects * 1.3.0 2019-09-03 [1] local 54 | psych 1.8.12 2019-01-12 [1] CRAN (R 3.5.0) 55 | purrr * 0.3.2 2019-03-15 [1] CRAN (R 3.5.0) 56 | R6 2.4.0 2019-02-14 [1] CRAN (R 3.5.0) 57 | Rcpp 1.0.2 2019-07-25 [1] CRAN (R 3.5.0) 58 | readr * 1.3.1 2018-12-21 [1] CRAN (R 3.5.0) 59 | readxl 1.1.0 2018-04-20 [2] CRAN (R 3.5.0) 60 | reshape2 1.4.3 2017-12-11 [2] CRAN (R 3.5.0) 61 | rlang 0.4.0 2019-06-25 [1] CRAN (R 3.5.0) 62 | rmarkdown 1.12 2019-03-14 [1] CRAN (R 3.5.0) 63 | rprojroot 1.3-2 2018-01-03 [2] CRAN (R 3.5.0) 64 | rstudioapi 0.7 2017-09-07 [2] CRAN (R 3.5.0) 65 | rvest 0.3.2 2016-06-17 [2] CRAN (R 3.5.0) 66 | scales 1.0.0 2018-08-09 [1] CRAN (R 3.5.0) 67 | sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.5.0) 68 | stringi 1.4.3 2019-03-12 [1] CRAN (R 3.5.0) 69 | stringr * 1.4.0 2019-02-10 [1] CRAN (R 3.5.0) 70 | tibble * 2.1.3 2019-06-06 [1] CRAN (R 3.5.0) 71 | tidyr * 0.8.99.9000 2019-08-23 [1] Github (tidyverse/tidyr@a3431e3) 72 | tidyselect 0.2.5 2018-10-11 [1] CRAN (R 3.5.0) 73 | tidyverse * 1.2.1 2017-11-14 [2] CRAN (R 3.5.0) 74 | vctrs 0.2.0 2019-07-05 [1] CRAN (R 3.5.0) 75 | withr 2.1.2 2018-03-15 [2] CRAN (R 3.5.0) 76 | xfun 0.7 2019-05-14 [1] CRAN (R 3.5.0) 77 | xml2 1.2.0 2018-01-24 [2] CRAN (R 3.5.0) 78 | yaml 2.2.0 2018-07-25 [1] CRAN (R 3.5.0) 79 | zeallot 0.1.0 2018-01-28 [1] CRAN (R 3.5.0) 80 | 81 | [1] /home/kriegen/R/x86_64-pc-linux-gnu-library/3.5 82 | [2] /opt/R-3.5.0/lib64/R/library 83 | -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/style.css: -------------------------------------------------------------------------------- 1 | body{ /* Normal */ 2 | font-size: 12px; 3 | } 4 | td { /* Table */ 5 | font-size: 11px; 6 | } 7 | h1.title { 8 | font-size: 18px; 9 | color: DarkGreen; 10 | } 11 | h1 { /* Header 1 */ 12 | font-size: 16px; 13 | font-weight: bold; 14 | color: DarkRed; 15 | } 16 | h2 { /* Header 2 */ 17 | font-size: 12px; 18 | font-weight: bold; 19 | font-style: italic; 20 | color: Black; 21 | } 22 | h3 { /* Header 3 */ 23 | font-size: 11px; 24 | color: Black; 25 | } 26 | code.r{ /* Code block */ 27 | font-size: 10px; 28 | } 29 | pre { /* Code block - determines code spacing between lines */ 30 | font-size: 10px; 31 | } 32 | -------------------------------------------------------------------------------- /demonstration/projects/p0012/progs/styles.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/demonstration/projects/p0012/progs/styles.docx -------------------------------------------------------------------------------- /inst/extdata/ptype_data_creator.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ptype data creator" 3 | --- 4 | 5 | ```{r} 6 | local({ 7 | projects_ptype <- 8 | dplyr::tibble( 9 | id = integer(), 10 | title = character(), 11 | short_title = character(), 12 | current_owner = projects:::new_projects_author(), 13 | status = character(), 14 | deadline_type = character(), 15 | deadline = lubridate::as_datetime(character()), 16 | stage = projects:::new_projects_stage(), 17 | impact = numeric(), 18 | path = character(), 19 | corresp_auth = projects:::new_projects_author(), 20 | creator = projects:::new_projects_author() 21 | ) 22 | 23 | tasks_ptype <- 24 | dplyr::tibble( 25 | PID = integer(), 26 | TID = integer(), 27 | done = integer(), 28 | task = character(), 29 | effort = double(), 30 | timing = double(), 31 | lead = projects:::new_projects_author(), 32 | status = character() 33 | ) 34 | 35 | authors_ptype <- 36 | dplyr::tibble( 37 | id = integer(), 38 | last_name = character(), 39 | given_names = character(), 40 | title = character(), 41 | degree = character(), 42 | email = character(), 43 | phone = character() 44 | ) 45 | 46 | affiliations_ptype <- 47 | dplyr::tibble( 48 | id = integer(), 49 | department_name = character(), 50 | institution_name = character(), 51 | address = character() 52 | ) 53 | 54 | assoc_ptype <- dplyr::tibble(id1 = integer(), id2 = integer()) 55 | 56 | usethis::use_data( 57 | projects_ptype, tasks_ptype, authors_ptype, affiliations_ptype, assoc_ptype, 58 | internal = TRUE, 59 | overwrite = TRUE 60 | ) 61 | }) 62 | ``` 63 | 64 | -------------------------------------------------------------------------------- /inst/templates/02_datawork.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | ```{r setup} 5 | library(projects) 6 | library(here) 7 | library(tidyverse) 8 | ``` 9 | 10 | 11 | ```{r read_raw_data} 12 | read_csv(file = ) 13 | ``` 14 | 15 | 16 | ```{r data_wrangling} 17 | 18 | ``` 19 | 20 | 21 | ```{r saver} 22 | save(..., file = here("/data/02_datawork_objects.RData")) 23 | save_session_info(here("progs", "session_info", "datawork")) 24 | ``` 25 | -------------------------------------------------------------------------------- /inst/templates/03_analysis.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | ```{r setup} 5 | library(projects) 6 | library(here) 7 | library(tidyverse) 8 | ``` 9 | 10 | 11 | ```{r load_02_datawork_data} 12 | load(file = here("/data/02_datawork_objects.RData")) 13 | ``` 14 | 15 | 16 | ```{r analysis} 17 | 18 | ``` 19 | 20 | 21 | ```{r saver} 22 | save(..., file = here("/data/03_analysis_objects.RData")) 23 | save_session_info(here("progs", "session_info", "analysis")) 24 | ``` 25 | -------------------------------------------------------------------------------- /inst/templates/04_report.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | word_document: 4 | reference_docx: styles.docx 5 | html_document: 6 | css: style.css 7 | pdf_document: 8 | default 9 | bibliography: citations.bib 10 | --- 11 | 12 | Funding: 13 | 14 | ```{r setup, include=FALSE} 15 | knitr::opts_chunk$set(echo = TRUE) 16 | 17 | library(projects) 18 | library(here) 19 | library(tidyverse) 20 | ``` 21 | 22 | ```{r load_03_analysis_data, include=FALSE} 23 | load(file = here("/data/03_analysis_objects.RData")) 24 | ``` 25 | 26 | # Abstract 27 | 28 | xxxxxxxx 29 | 30 | \pagebreak 31 | 32 | # Introduction 33 | 34 | xxxxxxxx 35 | 36 | # Methods 37 | 38 | xxxxxxxx 39 | 40 | # Results 41 | 42 | xxxxxxxx 43 | 44 | # Discussion 45 | 46 | xxxxxxxx 47 | 48 | \pagebreak 49 | 50 | ## References 51 | 52 | ```{r session_info, include=FALSE} 53 | save_session_info(here("progs", "session_info", "report")) 54 | ``` 55 | 56 | -------------------------------------------------------------------------------- /inst/templates/CONSORT_protocol.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | word_document: 4 | reference_docx: styles.docx 5 | html_document: 6 | css: style.css 7 | pdf_document: 8 | default 9 | bibliography: citations.bib 10 | --- 11 | 12 | Funding: 13 | 14 | \pagebreak 15 | 16 | ```{r setup, include=FALSE} 17 | knitr::opts_chunk$set(echo = TRUE) 18 | 19 | library(projects) 20 | library(here) 21 | library(tidyverse) 22 | ``` 23 | 24 | # Abstract 25 | 1a Identification as a randomised trial in the title 26 | 1b Structured summary of trial design, methods, results, and conclusions (for specific guidance see CONSORT for abstracts) 27 | 28 | # Introduction 29 | 30 | ## Background/rationale 31 | Scientific background and explanation of rationale 32 | 33 | ## Objectives 34 | Specific objectives or hypotheses 35 | 36 | # Methods 37 | 38 | ## Trial design 39 | Description of trial design (such as parallel, factorial) including allocation ratio 40 | Important changes to methods after trial commencement (such as eligibility criteria), with reasons 41 | 42 | ## Participants 43 | Eligibility criteria for participants 44 | Settings and locations where the data were collected 45 | 46 | ## Interventions 47 | The interventions for each group with sufficient details to allow replication, including how and when they were actually administered 48 | 49 | ## Outcomes 50 | Completely defined pre-specified primary and secondary outcome measures, including how and when they were assessed 51 | Any changes to trial outcomes after the trial commenced, with reasons 52 | 53 | ## Sample size 54 | How sample size was determined 55 | When applicable, explanation of any interim analyses and stopping guidelines 56 | 57 | ## Randomisation: 58 | 59 | ### Sequence generation 60 | Method used to generate the random allocation sequence 61 | Type of randomisation; details of any restriction (such as blocking and block size) 62 | 63 | ### Allocation concealment mechanism 64 | Mechanism used to implement the random allocation sequence (such as sequentially numbered containers), describing any steps taken to conceal the sequence until interventions were assigned 65 | 66 | ### Implementation 67 | Who generated the random allocation sequence, who enrolled participants, and who assigned participants to interventions 68 | 69 | ## Blinding 70 | If done, who was blinded after assignment to interventions (for example, participants, care providers, those assessing outcomes) and how 71 | If relevant, description of the similarity of interventions 72 | 73 | ## Statistical methods 74 | Statistical methods used to compare groups for primary and secondary outcomes 75 | Methods for additional analyses, such as subgroup analyses and adjusted analyses 76 | 77 | # Results 78 | 79 | ## Participant flow (a diagram is strongly recommended) 80 | For each group, the numbers of participants who were randomly assigned, received intended treatment, and were analysed for the primary outcome 81 | For each group, losses and exclusions after randomisation, together with reasons 82 | 83 | ## Recruitment 84 | Dates defining the periods of recruitment and follow-up 85 | Why the trial ended or was stopped 86 | 87 | ## Baseline data 88 | A table showing baseline demographic and clinical characteristics for each group 89 | 90 | ## Numbers analysed 91 | For each group, number of participants (denominator) included in each analysis and whether the analysis was by original assigned groups 92 | 93 | ## Outcomes and estimation 94 | For each primary and secondary outcome, results for each group, and the estimated effect size and its precision (such as 95% confidence interval) 95 | For binary outcomes, presentation of both absolute and relative effect sizes is recommended 96 | 97 | ## Ancillary analyses 98 | Results of any other analyses performed, including subgroup analyses and adjusted analyses, distinguishing pre-specified from exploratory 99 | 100 | ## Harms 101 | All important harms or unintended effects in each group (for specific guidance see CONSORT for harms) 102 | 103 | # Discussion 104 | ## Limitations 105 | Trial limitations, addressing sources of potential bias, imprecision, and, if relevant, multiplicity of analyses 106 | 107 | ## Generalisability 108 | Generalisability (external validity, applicability) of the trial findings 109 | 110 | ## Interpretation 111 | Interpretation consistent with results, balancing benefits and harms, and considering other relevant evidence 112 | 113 | # Other information 114 | 115 | ## Registration 116 | Registration number and name of trial registry 117 | 118 | ## Protocol 119 | Where the full trial protocol can be accessed, if available 120 | 121 | ## Funding 122 | Sources of funding and other support (such as supply of drugs), role of funders 123 | 124 | \pagebreak 125 | 126 | ## References 127 | 128 | ```{r session_info, include=FALSE} 129 | save_session_info(here("progs", "session_info", "protocol")) 130 | ``` 131 | -------------------------------------------------------------------------------- /inst/templates/STROBE_protocol.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | word_document: 4 | reference_docx: styles.docx 5 | html_document: 6 | css: style.css 7 | pdf_document: 8 | default 9 | bibliography: citations.bib 10 | --- 11 | 12 | Funding: 13 | 14 | \pagebreak 15 | 16 | ```{r setup, include=FALSE} 17 | knitr::opts_chunk$set(echo = TRUE) 18 | 19 | library(projects) 20 | library(here) 21 | library(tidyverse) 22 | ``` 23 | 24 | # Abstract 25 | (a) Indicate the study’s design with a commonly used term in the title or the abstract 26 | (b) Provide in the abstract an informative and balanced summary of what was done and what was found 27 | 28 | # Introduction 29 | 30 | ## Background/rationale 31 | Explain the scientific background and rationale for the investigation being reported 32 | 33 | ## Objectives 34 | State specific objectives, including any prespecified hypotheses 35 | 36 | # Methods 37 | 38 | ##Study design 39 | Present key elements of study design early in the paper 40 | 41 | ## Setting 42 | Describe the setting, locations, and relevant dates, including periods of recruitment, exposure, follow-up, and data collection 43 | 44 | ## Participants 45 | (a) *Cohort study*—Give the eligibility criteria, and the sources and methods of selection of participants. Describe methods of follow-up 46 | *Case-control study*—Give the eligibility criteria, and the sources and methods of case ascertainment and control selection. Give the rationale for the choice of cases and controls 47 | *Cross-sectional study*—Give the eligibility criteria, and the sources and methods of selection of participants 48 | 49 | (b) *Cohort study*—For matched studies, give matching criteria and number of exposed and unexposed 50 | *Case-control study*—For matched studies, give matching criteria and the number of controls per case 51 | 52 | ## Variables 53 | Clearly define all outcomes, exposures, predictors, potential confounders, and effect modifiers. Give diagnostic criteria, if applicable 54 | 55 | ## Data sources/ measurement 56 | For each variable of interest, give sources of data and details of methods of assessment (measurement). Describe comparability of assessment methods if there is more than one group 57 | 58 | ## Bias 59 | Describe any efforts to address potential sources of bias 60 | 61 | ## Study size 62 | Explain how the study size was arrived at 63 | 64 | ## Quantitative variables 65 | Explain how quantitative variables were handled in the analyses. If applicable, describe which groupings were chosen and why 66 | 67 | ## Statistical methods 68 | (a) Describe all statistical methods, including those used to control for confounding 69 | (b) Describe any methods used to examine subgroups and interactions 70 | (c) Explain how missing data were addressed 71 | (d) *Cohort study*—If applicable, explain how loss to follow-up was addressed 72 | *Case-control study*—If applicable, explain how matching of cases and controls was addressed 73 | *Cross-sectional study*—If applicable, describe analytical methods taking account of sampling strategy 74 | (e) Describe any sensitivity analyses 75 | 76 | # Results 77 | 78 | ## Participants 79 | (a) Report numbers of individuals at each stage of study—eg numbers potentially eligible, examined for eligibility, confirmed eligible, included in the study, completing follow-up, and analysed 80 | (b) Give reasons for non-participation at each stage 81 | (c) Consider use of a flow diagram 82 | 83 | ## Descriptive data 84 | (a) Give characteristics of study participants (eg demographic, clinical, social) and information on exposures and potential confounders 85 | (b) Indicate number of participants with missing data for each variable of interest 86 | (c) Cohort study—Summarise follow-up time (eg, average and total amount) 87 | 88 | ## Outcome data 89 | *Cohort study*—Report numbers of outcome events or summary measures over time 90 | *Case-control study*—Report numbers in each exposure category, or summary measures of exposure 91 | *Cross-sectional study*—Report numbers of outcome events or summary measures 92 | 93 | ## Main results 94 | (a) Give unadjusted estimates and, if applicable, confounder-adjusted estimates and their precision (eg, 95% confidence interval). Make clear which confounders were adjusted for and why they were included 95 | (b) Report category boundaries when continuous variables were categorized 96 | (c) If relevant, consider translating estimates of relative risk into absolute risk for a meaningful time period 97 | 98 | ## Other analyses 99 | Report other analyses done—eg analyses of subgroups and interactions, and sensitivity analyses 100 | 101 | # Discussion 102 | 103 | ## Key results 104 | Summarise key results with reference to study objectives 105 | 106 | ## Limitations 107 | Discuss limitations of the study, taking into account sources of potential bias or imprecision. Discuss both direction and magnitude of any potential bias 108 | 109 | ## Interpretation 110 | Give a cautious overall interpretation of results considering objectives, limitations, multiplicity of analyses, results from similar studies, and other relevant evidence 111 | 112 | ## Generalisability 113 | Discuss the generalisability (external validity) of the study results 114 | 115 | \pagebreak 116 | 117 | ## References 118 | 119 | ```{r session_info, include=FALSE} 120 | save_session_info(here("progs", "session_info", "protocol")) 121 | ``` 122 | -------------------------------------------------------------------------------- /inst/templates/citations.bib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/inst/templates/citations.bib -------------------------------------------------------------------------------- /inst/templates/pXXXX.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /inst/templates/style.css: -------------------------------------------------------------------------------- 1 | body{ /* Normal */ 2 | font-size: 11px; 3 | } 4 | td { /* Table */ 5 | font-size: 11px; 6 | } 7 | h1.title { 8 | font-size: 24px; 9 | color: DarkRed; 10 | } 11 | h1 { /* Header 1 */ 12 | font-size: 14px; 13 | font-weight: bold; 14 | color: DarkRed; 15 | } 16 | h2 { /* Header 2 */ 17 | font-size: 12px; 18 | font-weight: bold; 19 | font-style: italic; 20 | color: Black; 21 | } 22 | h3 { /* Header 3 */ 23 | font-size: 11px; 24 | color: Black; 25 | } 26 | code.r{ /* Code block */ 27 | font-size: 10px; 28 | } 29 | pre { /* Code block - determines code spacing between lines */ 30 | font-size: 10px; 31 | } 32 | -------------------------------------------------------------------------------- /inst/templates/styles.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/inst/templates/styles.docx -------------------------------------------------------------------------------- /man/README/README-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClevelandClinicQHS/projects/6e7cd6277b79887b0bbc95c2d3c7050b2d845094/man/README/README-workflow.png -------------------------------------------------------------------------------- /man/README/citations.bib: -------------------------------------------------------------------------------- 1 | @article{baker20161, 2 | title={1,500 scientists lift the lid on reproducibility}, 3 | author={Baker, Monya}, 4 | journal={Nature News}, 5 | volume={533}, 6 | number={7604}, 7 | pages={452}, 8 | year={2016} 9 | } 10 | 11 | @article {Gilbert1037, 12 | author = {Gilbert, Daniel T. and King, Gary and Pettigrew, Stephen and Wilson, Timothy D.}, 13 | title = {Comment on {\textquotedblleft}Estimating the reproducibility of psychological science{\textquotedblright}}, 14 | volume = {351}, 15 | number = {6277}, 16 | pages = {1037--1037}, 17 | year = {2016}, 18 | doi = {10.1126/science.aad7243}, 19 | publisher = {American Association for the Advancement of Science}, 20 | abstract = {A paper from the Open Science Collaboration (Research Articles, 28 August 2015, aac4716) attempting to replicate 100 published studies suggests that the reproducibility of psychological science is surprisingly low. We show that this article contains three statistical errors and provides no support for such a conclusion. Indeed, the data are consistent with the opposite conclusion, namely, that the reproducibility of psychological science is quite high.}, 21 | issn = {0036-8075}, 22 | URL = {http://science.sciencemag.org/content/351/6277/1037.2}, 23 | eprint = {http://science.sciencemag.org/content/351/6277/1037.2.full.pdf}, 24 | journal = {Science} 25 | } 26 | 27 | @article {aac4716, 28 | author = {The Open Science Collaboration,}, 29 | title = {Estimating the reproducibility of psychological science}, 30 | volume = {349}, 31 | number = {6251}, 32 | elocation-id = {aac4716}, 33 | year = {2015}, 34 | doi = {10.1126/science.aac4716}, 35 | publisher = {American Association for the Advancement of Science}, 36 | abstract = {One of the central goals in any scientific endeavor is to understand causality. Experiments that seek to demonstrate a cause/effect relation most often manipulate the postulated causal factor. Aarts et al. describe the replication of 100 experiments reported in papers published in 2008 in three high-ranking psychology journals. Assessing whether the replication and the original experiment yielded the same result according to several criteria, they find that about one-third to one-half of the original findings were also observed in the replication study.Science, this issue 10.1126/science.aac4716INTRODUCTIONReproducibility is a defining feature of science, but the extent to which it characterizes current research is unknown. Scientific claims should not gain credence because of the status or authority of their originator but by the replicability of their supporting evidence. Even research of exemplary quality may have irreproducible empirical findings because of random or systematic error.RATIONALEThere is concern about the rate and predictors of reproducibility, but limited evidence. Potentially problematic practices include selective reporting, selective analysis, and insufficient specification of the conditions necessary or sufficient to obtain the results. Direct replication is the attempt to recreate the conditions believed sufficient for obtaining a previously observed finding and is the means of establishing reproducibility of a finding with new data. We conducted a large-scale, collaborative effort to obtain an initial estimate of the reproducibility of psychological science.RESULTSWe conducted replications of 100 experimental and correlational studies published in three psychology journals using high-powered designs and original materials when available. There is no single standard for evaluating replication success. Here, we evaluated reproducibility using significance and P values, effect sizes, subjective assessments of replication teams, and meta-analysis of effect sizes. The mean effect size (r) of the replication effects (Mr = 0.197, SD = 0.257) was half the magnitude of the mean effect size of the original effects (Mr = 0.403, SD = 0.188), representing a substantial decline. Ninety-seven percent of original studies had significant results (P \< .05). Thirty-six percent of replications had significant results; 47\% of original effect sizes were in the 95\% confidence interval of the replication effect size; 39\% of effects were subjectively rated to have replicated the original result; and if no bias in original results is assumed, combining original and replication results left 68\% with statistically significant effects. Correlational tests suggest that replication success was better predicted by the strength of original evidence than by characteristics of the original and replication teams.CONCLUSIONNo single indicator sufficiently describes replication success, and the five indicators examined here are not the only ways to evaluate reproducibility. Nonetheless, collectively these results offer a clear conclusion: A large portion of replications produced weaker evidence for the original findings despite using materials provided by the original authors, review in advance for methodological fidelity, and high statistical power to detect the original effect sizes. Moreover, correlational evidence is consistent with the conclusion that variation in the strength of initial evidence (such as original P value) was more predictive of replication success than variation in the characteristics of the teams conducting the research (such as experience and expertise). The latter factors certainly can influence replication success, but they did not appear to do so here.Reproducibility is not well understood because the incentives for individual scientists prioritize novelty over replication. Innovation is the engine of discovery and is vital for a productive, effective scientific enterprise. However, innovative ideas become old news fast. Journal reviewers and editors may dismiss a new test of a published idea as unoriginal. The claim that {\textquotedblleft}we already know this{\textquotedblright} belies the uncertainty of scientific evidence. Innovation points out paths that are possible; replication points out paths that are likely; progress relies on both. Replication can increase certainty when findings are reproduced and promote innovation when they are not. This project provides accumulating evidence for many findings in psychological research and suggests that there is still more work to do to verify whether we know what we think we know.Original study effect size versus replication effect size (correlation coefficients).Diagonal line represents replication effect size equal to original effect size. Dotted line represents replication effect size of 0. Points below the dotted line were effects in the opposite direction of the original. Density plots are separated by significant (blue) and nonsignificant (red) effects.Reproducibility is a defining feature of science, but the extent to which it characterizes current research is unknown. We conducted replications of 100 experimental and correlational studies published in three psychology journals using high-powered designs and original materials when available. Replication effects were half the magnitude of original effects, representing a substantial decline. Ninety-seven percent of original studies had statistically significant results. Thirty-six percent of replications had statistically significant results; 47\% of original effect sizes were in the 95\% confidence interval of the replication effect size; 39\% of effects were subjectively rated to have replicated the original result; and if no bias in original results is assumed, combining original and replication results left 68\% with statistically significant effects. Correlational tests suggest that replication success was better predicted by the strength of original evidence than by characteristics of the original and replication teams.}, 37 | issn = {0036-8075}, 38 | URL = {http://science.sciencemag.org/content/349/6251/aac4716}, 39 | eprint = {http://science.sciencemag.org/content/349/6251/aac4716.full.pdf}, 40 | journal = {Science} 41 | } 42 | 43 | @article {Nosek1422, 44 | author = {Nosek, B. A. and Alter, G. and Banks, G. C. and Borsboom, D. and Bowman, S. D. and Breckler, S. J. and Buck, S. and Chambers, C. D. and Chin, G. and Christensen, G. and Contestabile, M. and Dafoe, A. and Eich, E. and Freese, J. and Glennerster, R. and Goroff, D. and Green, D. P. and Hesse, B. and Humphreys, M. and Ishiyama, J. and Karlan, D. and Kraut, A. and Lupia, A. and Mabry, P. and Madon, T. and Malhotra, N. and Mayo-Wilson, E. and McNutt, M. and Miguel, E. and Paluck, E. Levy and Simonsohn, U. and Soderberg, C. and Spellman, B. A. and Turitto, J. and VandenBos, G. and Vazire, S. and Wagenmakers, E. J. and Wilson, R. and Yarkoni, T.}, 45 | title = {Promoting an open research culture}, 46 | volume = {348}, 47 | number = {6242}, 48 | pages = {1422--1425}, 49 | year = {2015}, 50 | doi = {10.1126/science.aab2374}, 51 | publisher = {American Association for the Advancement of Science}, 52 | issn = {0036-8075}, 53 | URL = {http://science.sciencemag.org/content/348/6242/1422}, 54 | eprint = {http://science.sciencemag.org/content/348/6242/1422.full.pdf}, 55 | journal = {Science} 56 | } 57 | 58 | @Manual{workflowr, 59 | title = {workflowr: A Framework for Reproducible and Collaborative Data Science}, 60 | author = {John Blischak and Peter Carbonetto and Matthew Stephens}, 61 | year = {2018}, 62 | note = {R package version 1.1.1}, 63 | url = {https://CRAN.R-project.org/package=workflowr}, 64 | } 65 | -------------------------------------------------------------------------------- /man/display_metadata.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getters.R 3 | \name{affiliations} 4 | \alias{affiliations} 5 | \alias{authors} 6 | \alias{tasks} 7 | \alias{display_metadata} 8 | \alias{projects} 9 | \alias{ideas} 10 | \alias{manuscripts} 11 | \title{View the \code{projects()}, \code{tasks()}, \code{authors()}, and 12 | \code{affiliations()} tables} 13 | \usage{ 14 | affiliations(affiliation, authors = FALSE) 15 | 16 | authors(author, affiliations = FALSE, projects = FALSE) 17 | 18 | tasks(project, lead, archived = FALSE) 19 | 20 | projects( 21 | project, 22 | all_stages = FALSE, 23 | exclude = c(0L, 6L), 24 | path = NULL, 25 | archived = FALSE, 26 | verbose = FALSE, 27 | authors = FALSE 28 | ) 29 | 30 | ideas(project, archived = FALSE, verbose = FALSE, authors = FALSE) 31 | 32 | manuscripts(project, archived = FALSE, verbose = FALSE, authors = FALSE) 33 | } 34 | \arguments{ 35 | \item{projects, authors, affiliations}{Logical values indicating whether or not 36 | to perform a left join with another metadata tibble. All \code{FALSE} by 37 | default.} 38 | 39 | \item{project, author, affiliation, lead}{An optional unique vector of 40 | \code{id}s and/or names. Only rows matching one or more entries will be 41 | returned. This is the one setting in which the package does not return 42 | throw an error if user input matches multiple projects.} 43 | 44 | \item{archived}{Logical, indicating whether or not to include projects that 45 | have been archived using \code{\link{archive_project}()}. \code{FALSE} by 46 | default.} 47 | 48 | \item{all_stages}{Logical, indicating whether or not to include projects of 49 | all stages, \strong{overriding the} \code{exclude} \strong{argument}.} 50 | 51 | \item{exclude}{A vector of numbers or character strings that can be validated 52 | against the list of project stages: 53 | 54 | \code{0: idea}\cr \code{1: design}\cr \code{2: data collection}\cr \code{3: 55 | analysis}\cr \code{4: manuscript}\cr \code{5: under review}\cr \code{6: 56 | accepted} 57 | 58 | \emph{Ignored if} \code{all_stages = TRUE}} 59 | 60 | \item{path}{A single file path of a directory within the main projects 61 | folder; only projects whose folder is in this directory will be returned.} 62 | 63 | \item{verbose}{Logical, indicating whether or not to return all columns of 64 | the \code{\link{projects}()}; if \code{FALSE}, only the \code{id}, 65 | \code{current_owner}, \code{status}, and \code{stage} columns are returned. 66 | Defaults to \code{FALSE}.} 67 | } 68 | \value{ 69 | A \code{\link[tibble]{tibble}}. 70 | } 71 | \description{ 72 | Returns a table of the projects/tasks/authors/affiliations, filtered and 73 | joined according to the entirely optional arguments. 74 | } 75 | \details{ 76 | \code{ideas()} is a shortcut for \code{projects(exclude = 1:6)} (including 77 | only projects of stage \code{0: idea}). 78 | 79 | \code{manuscripts()} is a shortcut for \code{projects(exclude = c(0:3, 6))} 80 | (yielding only projects of stage \code{4: manuscript} and \code{5: under 81 | review}). 82 | 83 | If one or more of the \code{projects}, \code{authors}, or \code{affiliations} 84 | arguments is set to \code{TRUE}, a \code{dplyr::\link[dplyr]{left_join}()} is 85 | performed, with the "left" table being the one sharing the name of the 86 | function being used. As such, rows that don't have matches in any other 87 | tables will still show up in the output, and rows that have multiple matches 88 | in other tables will yield multiple rows in the output. The "right" table's 89 | \code{id} column (if present) will be renamed. 90 | } 91 | \examples{ 92 | ############################################################################# 93 | # SETUP 94 | old_home <- Sys.getenv("HOME") 95 | old_ppath <- Sys.getenv("PROJECTS_FOLDER_PATH") 96 | temp_dir <- tempfile("dir") 97 | dir.create(temp_dir) 98 | Sys.unsetenv("PROJECTS_FOLDER_PATH") 99 | Sys.setenv(HOME = temp_dir) 100 | setup_projects(path = temp_dir) 101 | new_affiliation(department_name = "Math Dept.", 102 | institution_name = "Springfield College", 103 | address = "123 College St, Springfield, AB") 104 | new_affiliation(department_name = "Art Department", 105 | institution_name = "Springfield College", 106 | address = "321 University Boulevard, Springfield, AB", 107 | id = 42) 108 | new_affiliation(department_name = "Central Intelligence Agency", 109 | institution_name = "United States Government", 110 | address = "888 Classified Dr, Washington DC") 111 | new_affiliation(department_name = "Pyrotechnics", 112 | institution_name = "ACME") 113 | new_author(given_names = "Spiro", last_name = "Agnew", degree = "LLB", 114 | affiliations = "Art D", id = 13) 115 | new_author(given_names = "Plato", id = 303) 116 | new_author(given_names = "Condoleezza", last_name = "Rice", 117 | affiliations = c(1, 42, "Agency", "ACME")) 118 | new_project(title = "Test project 1", current_owner = "Plato", stage = 1) 119 | new_project(title = "Test project 2", current_owner = "eezza", stage = 2) 120 | new_project(title = "Test project 3", current_owner = "Plato", stage = 3) 121 | new_project(title = "Fun project 4", current_owner = "Rice", stage = 4) 122 | new_project(title = "Fun project 5", current_owner = "Rice", stage = 5) 123 | new_project(title = "Fun project 6", current_owner = "Rice", stage = 6) 124 | new_project(title = "Good idea", current_owner = "Rice", stage = 0) 125 | new_task(2, "take a break", lead = "eezza", done = 1) 126 | new_task(2, "go home", TID = 1, lead = 303, timing = 1337) 127 | new_task(1, "tie up loose ends", status = "untying a knot", effort = Inf) 128 | new_task(3, "cook dinner", lead = "plato") 129 | ############################################################################# 130 | 131 | # View entire affiliations table 132 | affiliations() 133 | 134 | # View authors table joined to affiliations table 135 | # Notice that multiple rows are created for each affiliation-author combination 136 | authors(affiliations = TRUE) 137 | 138 | # View only active projects with "Fun" in their title. 139 | projects("Fun") 140 | 141 | # View all projects with "Rice" as the current_owner 142 | projects(all_stages = TRUE) \%>\% dplyr::filter(current_owner == "Rice") 143 | 144 | # View manuscripts 145 | manuscripts() 146 | 147 | # View ideas 148 | ideas() 149 | 150 | # View tasks 151 | tasks() 152 | 153 | # View only Project 1's tasks 154 | tasks(1) 155 | 156 | # View only Plato's tasks 157 | tasks(lead = "plato") 158 | 159 | # View only Plato's tasks in project 1 160 | tasks(1, "plato") 161 | 162 | # Wrapped in if (interactive()) because it requires interactive console input 163 | # and fails automated testing. 164 | if (interactive()) { 165 | # Archive Fun project 5 166 | archive_project("Fun project 5") 167 | 168 | # Default behavior is to not include archived projects in projects() table 169 | projects("Fun") 170 | projects("Fun", archived = TRUE) 171 | } 172 | 173 | ############################################################################# 174 | # CLEANUP 175 | # (or, the user can just restart R) 176 | Sys.setenv(HOME = old_home, PROJECTS_FOLDER_PATH = old_ppath) 177 | } 178 | -------------------------------------------------------------------------------- /man/email_authors.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/email_authors.R 3 | \name{email_authors} 4 | \alias{email_authors} 5 | \title{Write an email to project authors} 6 | \usage{ 7 | email_authors( 8 | project = NULL, 9 | browser = getOption("browser"), 10 | encodeIfNeeded = FALSE 11 | ) 12 | } 13 | \arguments{ 14 | \item{project}{Project \code{id} or unambiguous substring of the project name 15 | from the \code{\link{projects}()} table. Defaults to \code{NULL} (see 16 | \strong{Details}).} 17 | 18 | \item{browser, encodeIfNeeded}{See \code{utils::\link[utils]{browseURL}()}.} 19 | } 20 | \description{ 21 | Invokes \code{utils::\link[utils]{browseURL}("mailto://[author emails]")} for 22 | a specified project, or for the currently open project if \code{project} is 23 | left as \code{NULL}. 24 | } 25 | \details{ 26 | The success of this function depends on the platform and the specified 27 | \code{browser}. See the \strong{Details} and \strong{URL schemes} sections of 28 | \code{utils::\link[utils]{browseURL}()}. 29 | 30 | If \code{project = NULL}, the function selects the project in the 31 | \code{\link{projects}()} table whose \code{path} is equal to 32 | \code{rstudioapi::\link[rstudioapi]{getActiveProject}()}. 33 | } 34 | \examples{ 35 | # Wrapped in if (interactive()) because this function is interactive by nature. 36 | if (interactive()) { 37 | 38 | # If you have a projects() project open, just run it: 39 | email_authors() 40 | 41 | # Otherwise, specify a project: 42 | 43 | ########################################################################### 44 | # Setup 45 | old_home <- Sys.getenv("HOME") 46 | old_ppath <- Sys.getenv("PROJECTS_FOLDER_PATH") 47 | temp_dir <- tempfile("dir") 48 | dir.create(temp_dir) 49 | Sys.unsetenv("PROJECTS_FOLDER_PATH") 50 | Sys.setenv(HOME = temp_dir) 51 | setup_projects(path = temp_dir) 52 | new_author("Rhonda", "Rondale", email = "ronda.rondale@co.uk") 53 | new_author("Betty", "Betts", email = "betty@co.uk") 54 | new_project("Inventing the Ring of Power", authors = c("Betty", "Ron")) 55 | ########################################################################### 56 | 57 | email_authors("Ring of Power") 58 | 59 | ########################################################################### 60 | # Cleanup (or just restart R) 61 | Sys.setenv(HOME = old_home, PROJECTS_FOLDER_PATH = old_ppath) 62 | } 63 | } 64 | \seealso{ 65 | \code{utils::\link[utils]{browseURL}()}; 66 | \code{rstudioapi::\link[rstudioapi]{getActiveProject}()} for information on 67 | \code{browser} and \code{encodeIfNeeded} arguments. 68 | } 69 | -------------------------------------------------------------------------------- /man/export_project.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/reproducibility.R 3 | \name{export_project} 4 | \alias{export_project} 5 | \title{Compress a project folder} 6 | \usage{ 7 | export_project(project, zipfile, include_hidden = FALSE, exclude = NULL) 8 | } 9 | \arguments{ 10 | \item{project}{Project \code{id} or unambiguous substring of the project name 11 | from the \code{\link{projects}()} table.} 12 | 13 | \item{zipfile}{Desired file path of the resulting compressed folder file, 14 | including the file's desired name and file extension. See the 15 | \code{zipfile} argument for the \code{zip::\link[zip]{zipr}()} function.} 16 | 17 | \item{include_hidden}{Logical indicating whether or not to include hidden 18 | folders and files (e.g., those with names that begin with a period). 19 | Defaults to \code{FALSE}.} 20 | 21 | \item{exclude}{Character vector of exact names of first-level subdirectories 22 | of the project folder to exclude from the resulting compressed folder file.} 23 | } 24 | \value{ 25 | The name of the created zip file, invisibly. 26 | } 27 | \description{ 28 | Creates a compressed file out of a user-specified project folder for sharing. 29 | } 30 | \details{ 31 | Currently, this function uses \code{zip::\link[zip]{zipr}()}. 32 | } 33 | -------------------------------------------------------------------------------- /man/file_management.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/file_management.R 3 | \name{file_management} 4 | \alias{file_management} 5 | \alias{new_project_group} 6 | \alias{rename_folder} 7 | \alias{move_project} 8 | \alias{copy_project} 9 | \alias{archive_project} 10 | \alias{open_project} 11 | \alias{move_projects_folder} 12 | \alias{rename_projects_folder} 13 | \title{file management} 14 | \usage{ 15 | new_project_group(path) 16 | 17 | rename_folder(project, new_folder_name, archived = FALSE) 18 | 19 | move_project(project, path, make_directories = FALSE, archived = FALSE) 20 | 21 | copy_project( 22 | project_to_copy, 23 | path, 24 | new_id = NA, 25 | new_folder_name = paste0("p", stringr::str_pad(new_id, 4, pad = "0")), 26 | new_short_title = NA, 27 | make_directories = FALSE, 28 | archived = FALSE 29 | ) 30 | 31 | archive_project(project) 32 | 33 | open_project(project, new_session = FALSE, archived = FALSE) 34 | 35 | move_projects_folder( 36 | new_path, 37 | make_directories = FALSE, 38 | .Renviron_path = file.path(Sys.getenv("HOME"), ".Renviron") 39 | ) 40 | 41 | rename_projects_folder( 42 | new_name, 43 | .Renviron_path = file.path(Sys.getenv("HOME"), ".Renviron") 44 | ) 45 | } 46 | \arguments{ 47 | \item{path}{A valid path string. 48 | 49 | For \code{copy_project()} only, if left blank, the preexisting project's 50 | directory is used. All other functions here require a valid path. 51 | 52 | See the \code{path} argument in \code{\link{new_project}()} for details on 53 | valid paths.} 54 | 55 | \item{project}{Project \code{id} or unambiguous substring of the project name 56 | from the \code{\link{projects}()} table} 57 | 58 | \item{new_folder_name}{Character string of new name for project folder. 59 | Always processed with \code{fs::\link[fs]{path_sanitize}()}.} 60 | 61 | \item{archived}{Logical indicating whether or not the function should 62 | consider archived projects when determining which project the user is 63 | referring to in the \code{project}/\code{project_to_copy} argument. 64 | \code{FALSE} by default. See \strong{Details}.} 65 | 66 | \item{make_directories}{Logical. If the path represented by the \code{path} 67 | parameter does not exist, should the needed directories be created?} 68 | 69 | \item{project_to_copy}{Project \code{id} or unambiguous substring of the 70 | project name corresponding to the project that is to be copied.} 71 | 72 | \item{new_id}{Optional integer, ranging from 1 to 9999, used as the 73 | newly-created project \code{id}. Must not already exist in 74 | \code{\link{projects}()$id}. If left blank, the lowest available \code{id} 75 | will be automatically used.} 76 | 77 | \item{new_short_title}{Optional character string that becomes the 78 | \code{short_title} of the project copy. It also becomes the project copy's 79 | folder name under normal circumstances (see \strong{Details}).} 80 | 81 | \item{new_session}{Same as the \code{newSession} argument in 82 | \code{rstudioapi::\link[rstudioapi]{openProject}()}.} 83 | 84 | \item{new_path}{A valid string indicating a path where the projects folder 85 | should be moved. The projects folder will have the same name, but it will 86 | be moved into this directory.} 87 | 88 | \item{.Renviron_path}{The full file path of the .Renviron file where the user 89 | would like to store the updated \code{\link{projects_folder}()} path. 90 | Default is the home .Renviron file. If the file doesn't exist it will be 91 | created. See also \code{\link{setup_projects}()}.} 92 | 93 | \item{new_name}{A valid directory name for the projects folder.} 94 | } 95 | \description{ 96 | Tools for Organizing and Managing Project Files 97 | } 98 | \details{ 99 | Projects can be moved (\code{move_project()}), copied 100 | (\code{copy_project()}), or archived (\code{archive_project}()). 101 | 102 | The difference between \code{delete_project()} and \code{archive_project()} 103 | is that the latter will just move the project to a directory called 104 | \emph{archive}, located in the same parent directory as the project. This 105 | directory gets created if it doesn't yet exist. Most functions that perform 106 | actions on projects will exclude archived projects by default in order to 107 | make it easier for the user to enter a nonambiguous string that will match an 108 | active (i.e., non-archived) project. 109 | 110 | Projects can also be organized into groups. By default, all projects are 111 | created within the main \link[=projects_folder]{projects folder}. To create a 112 | project group, which is essentially a subfolder of the main 113 | \link[=projects_folder]{projects folder}, use \code{new_project_group()}. 114 | 115 | \code{open_project()} is a wrapper around 116 | \code{rstudioapi::\link[rstudioapi]{openProject}()}, but the user only needs 117 | to know the project's \code{id}, \code{title}, or \code{short_title} instead 118 | of the file path of the project's \emph{.Rproj} file. If there is no 119 | \emph{.Rproj} file in the project's folder, the user has the option to 120 | restore a default \emph{.Rproj} file. If there are multiple \emph{.Rproj} 121 | files, an error is thrown. 122 | 123 | \code{move_projects_folder()} allows the user to move the entire projects 124 | folder created by \code{\link{setup_projects}()} into a different directory, 125 | and \code{rename_projects_folder()} changes its name. 126 | } 127 | \examples{ 128 | ############################################################################# 129 | # SETUP 130 | old_home <- Sys.getenv("HOME") 131 | old_ppath <- Sys.getenv("PROJECTS_FOLDER_PATH") 132 | temp_dir <- tempfile("dir") 133 | dir.create(temp_dir) 134 | Sys.unsetenv("PROJECTS_FOLDER_PATH") 135 | Sys.setenv(HOME = temp_dir) 136 | setup_projects(path = temp_dir) 137 | ############################################################################# 138 | 139 | # setting up a simple project directory tree 140 | new_project_group("kidney/clinical") 141 | new_project_group("kidney/genomics") 142 | new_project_group("prostate/clinical") 143 | new_project_group("prostate/genomics") 144 | 145 | # Wrapped in if (interactive()) because it requires interactive console input 146 | # and fails automated package checking and testing. 147 | if (interactive()){ 148 | new_project(title = "Sample Authorless Project", parent_directory = "kidney") 149 | 150 | # Moving the project folder, then moving it again. 151 | move_project(project = 1, "kidney/genomics") 152 | move_project(project = "Sample Authorless Project", "prostate/clinical") 153 | 154 | # Copying the project 155 | copy_project(project_to_copy = 1, "kidney/clinical") 156 | 157 | # Renaming the folder of the copy of the project 158 | rename_folder(project = 2, "copy") 159 | 160 | # Archiving the copy of the project 161 | archive_project(2) 162 | 163 | # Moving and renaming the entire projects folder 164 | temp_dir2 <- tempfile("dir") 165 | dir.create(temp_dir2) 166 | move_projects_folder(temp_dir2) 167 | projects_folder() 168 | rename_projects_folder("foobar") 169 | projects_folder() 170 | 171 | # Opens the project in same session 172 | open_project("Sample") 173 | 174 | # Opens the project in a new session 175 | open_project(1, new_session = TRUE) 176 | } 177 | ############################################################################# 178 | # CLEANUP 179 | Sys.setenv(HOME = old_home, PROJECTS_FOLDER_PATH = old_ppath) 180 | } 181 | \seealso{ 182 | \code{\link{new_project}()} and \code{\link{delete_project}()} for 183 | other functions that write and delete files. 184 | } 185 | -------------------------------------------------------------------------------- /man/header.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/header.R 3 | \name{header} 4 | \alias{header} 5 | \title{Print project header to console} 6 | \usage{ 7 | header(project, archived = FALSE) 8 | } 9 | \arguments{ 10 | \item{project}{Project \code{id} or unambiguous substring of the project name 11 | from the \code{\link{projects}()} table.} 12 | 13 | \item{archived}{Logical, indicating whether or not the function should 14 | consider archived projects when determining which project the user is 15 | referring to in the \code{project} argument. \code{FALSE} by default. 16 | 17 | See the \strong{Details} section of \code{\link{archive_project}()} for 18 | more information on the "archived" status of a project.} 19 | } 20 | \description{ 21 | Prints a header to the console to be copied and pasted into the YAML of a 22 | project protocol or manuscript R Markdown file. These lines essentially 23 | produce a title page when the R Markdown file is knitted. 24 | } 25 | \details{ 26 | The project header consists of: 27 | 28 | \enumerate{ 29 | 30 | \item the project title 31 | 32 | \item the author list 33 | 34 | \item the list of author affiliations 35 | 36 | \item corresponding author information 37 | 38 | } 39 | } 40 | \examples{ 41 | ############################################################################# 42 | # SETUP 43 | old_home <- Sys.getenv("HOME") 44 | old_ppath <- Sys.getenv("PROJECTS_FOLDER_PATH") 45 | temp_dir <- tempfile("dir") 46 | dir.create(temp_dir) 47 | Sys.unsetenv("PROJECTS_FOLDER_PATH") 48 | Sys.setenv(HOME = temp_dir) 49 | setup_projects(path = temp_dir) 50 | new_affiliation(department_name = "Math Dept.", 51 | institution_name = "Springfield College", 52 | address = "123 College St, Springfield, AB") 53 | new_affiliation(department_name = "Art Department", 54 | institution_name = "Springfield College", 55 | address = "321 University Boulevard, Springfield, AB", 56 | id = 42) 57 | new_affiliation(department_name = "Central Intelligence Agency", 58 | institution_name = "United States Government", 59 | address = "888 Classified Dr, Washington DC") 60 | new_affiliation(department_name = "Pyrotechnics", 61 | institution_name = "ACME") 62 | new_author(given_names = "Rosetta", last_name = "Stone", 63 | affiliations = c(42, "Math"), degree = "PhD", 64 | email = "slab@rock.net", phone = "867-555-5309", id = 8888) 65 | new_author(given_names = "Spiro", last_name = "Agnew", degree = "LLB", 66 | affiliations = "Art D", id = 13) 67 | new_author(given_names = "Plato", id = 303) 68 | new_project(title = "Test Project 1", authors = c(13, "303", "Stone"), 69 | corresp_auth = "Stone") 70 | ############################################################################# 71 | 72 | header(1) 73 | 74 | ############################################################################# 75 | # CLEANUP 76 | Sys.setenv(HOME = old_home, PROJECTS_FOLDER_PATH = old_ppath) 77 | } 78 | -------------------------------------------------------------------------------- /man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils-pipe.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe operator} 6 | \usage{ 7 | lhs \%>\% rhs 8 | } 9 | \description{ 10 | See \code{magrittr::\link[magrittr]{\%>\%}} for details. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/projects-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/projects.R 3 | \docType{package} 4 | \name{projects-package} 5 | \alias{projects-package} 6 | \title{projects: A project infrastructure for researchers.} 7 | \description{ 8 | The \code{projects} package provides a project infrastructure with a focus on 9 | manuscript creation. It creates a project folder with a single command, 10 | containing subdirectories for specific components, templates for manuscripts, 11 | and so on. 12 | } 13 | \section{Knitting}{ 14 | There are several functions that require interactive user 15 | confirmation via the console. Since interactive console input is 16 | incompatible with knitting via R Markdown files, the \code{projects} 17 | package was coded such that user confirmation is bypassed when 18 | \code{isTRUE(getOption('knitr.in.progress')) == TRUE}. Therefore, all 19 | \code{projects} package functions are usable when knitting. \strong{Knit 20 | with caution!} 21 | } 22 | 23 | \section{Acknowledgements}{ 24 | The authors of this package acknowledge the 25 | support provided by members of the Northeast Ohio Cohort for 26 | Atherosclerotic Risk Estimation (NEOCARE) investigative team: Claudia 27 | Coulton, Douglas Gunzler, Darcy Freedman, Neal Dawson, Michael Rothberg, 28 | David Zidar, David Kaelber, Douglas Einstadter, Alex Milinovich, Monica 29 | Webb Hooper, Kristen Hassmiller-Lich, Ye Tian (Devin), Kristen Berg, and 30 | Sandy Andrukat. 31 | } 32 | 33 | \section{Funding}{ 34 | This work was supported by The National Institute on Aging 35 | of the National Institutes of Health under award number R01AG055480. The 36 | content is solely the responsibility of the authors and does not 37 | necessarily represent the official views of the National Institutes of 38 | Health. 39 | } 40 | 41 | \seealso{ 42 | \code{\link{setup_projects}()} for getting started. 43 | } 44 | -------------------------------------------------------------------------------- /man/projects_author-vctrs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class-projects_author.R 3 | \name{vec_ptype2.projects_author} 4 | \alias{vec_ptype2.projects_author} 5 | \alias{vec_cast.projects_author} 6 | \alias{projects_author-vctrs} 7 | \title{Internal vctrs methods} 8 | \usage{ 9 | \method{vec_ptype2}{projects_author}(x, y, ...) 10 | 11 | \method{vec_cast}{projects_author}(x, to, ...) 12 | } 13 | \description{ 14 | Internal vctrs methods 15 | } 16 | \keyword{internal} 17 | -------------------------------------------------------------------------------- /man/projects_author.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class-projects_author.R 3 | \docType{class} 4 | \name{projects_author} 5 | \alias{projects_author} 6 | \alias{is_projects_author} 7 | \alias{projects_author-class} 8 | \alias{match.projects_author} 9 | \alias{match,projects_author,ANY-method} 10 | \alias{match,ANY,projects_author-method} 11 | \alias{match,projects_author,projects_author-method} 12 | \alias{\%in\%.projects_author} 13 | \alias{\%in\%,projects_author-method} 14 | \title{\code{projects_author} vector} 15 | \usage{ 16 | projects_author(x = character()) 17 | 18 | is_projects_author(x) 19 | 20 | match.projects_author(x, table, nomatch = NA_integer_, incomparables = NULL) 21 | 22 | \S4method{match}{projects_author,ANY}(x, table, nomatch = NA_integer_, incomparables = NULL) 23 | 24 | \S4method{match}{ANY,projects_author}(x, table, nomatch = NA_integer_, incomparables = NULL) 25 | 26 | \S4method{match}{projects_author,projects_author}(x, table, nomatch = NA_integer_, incomparables = NULL) 27 | 28 | `\%in\%.projects_author`(x, table) 29 | 30 | \S4method{\%in\%}{projects_author}(x, table) 31 | } 32 | \arguments{ 33 | \item{x}{For \code{projects_author()}, an integer or character vector. For 34 | \code{is_projects_author()}, an object to test. 35 | 36 | For \code{\link{match}()} and \code{\link{\%in\%}}, an integer, a character 37 | string, or a \code{projects_author} object. See \code{\link{match}()} and 38 | \strong{Equality and value matching methods} below.} 39 | 40 | \item{table}{An integer number, a character string, or a 41 | \code{projects_author} object. See \code{\link{match}()} and 42 | \strong{Equality and value matching methods} below.} 43 | 44 | \item{nomatch}{See \code{\link{match}()}.} 45 | 46 | \item{incomparables}{An integer number, a character string, or a 47 | \code{projects_author} object. See \code{\link{match}()}.} 48 | } 49 | \description{ 50 | Objects of this class contain both the \code{id} and the \code{last_name} of 51 | an author so that the package and the user, respectively, can easily identify 52 | the author. 53 | } 54 | \details{ 55 | Essentially, this is a character string of the form: 56 | 57 | \code{id: last_name} 58 | 59 | \code{projects_author()} coerces an integer or character vector to a 60 | \code{projects_author} object, validating each element against the existing 61 | \code{\link{authors}()} table. 62 | } 63 | \section{Numeric coercion methods}{ 64 | \code{\link{as.integer}()}, 65 | \code{\link{as.double}()}, and \code{\link{as.numeric}()} return the 66 | \code{id} portion of the \code{projects_author} object as an 67 | integer/double. The methods for the equality and value matching functions 68 | described below make use of these numeric coercion methods. Users desiring 69 | to apply value matching functions other than the ones described below may 70 | similarly take advantage of these. 71 | } 72 | 73 | \section{Equality and value matching methods}{ 74 | Methods for \code{\link{==}}, 75 | \code{\link{!=}}, \code{\link{match}()}, and \code{\link{\%in\%}} enable 76 | users to test equality and to value match among \code{projects_author} 77 | objects and as well as between \code{projects_author} objects and unclassed 78 | numbers/characters. When testing or matching against a numeric vector, the 79 | \code{projects_author} object is first coerced to an integer with the 80 | \code{as.integer()} method described above. When testing or matching 81 | against a character vector, the character vector is validated against the 82 | \code{\link{authors}()} table. 83 | } 84 | 85 | \examples{ 86 | ############################################################################# 87 | # SETUP 88 | old_home <- Sys.getenv("HOME") 89 | old_ppath <- Sys.getenv("PROJECTS_FOLDER_PATH") 90 | temp_dir <- tempfile("dir") 91 | dir.create(temp_dir) 92 | Sys.unsetenv("PROJECTS_FOLDER_PATH") 93 | Sys.setenv(HOME = temp_dir) 94 | setup_projects(path = temp_dir) 95 | new_author("chuck", "jonesman", id = 33) 96 | new_author("Hattie", "Hatsman", id = 45) 97 | ############################################################################# 98 | 99 | jones <- projects_author("33: Jones") 100 | 101 | jones 102 | 103 | as.integer(jones) # 33 104 | 105 | jones == 33 # TRUE 106 | jones == 10 # FALSE 107 | jones != 33 # FALSE 108 | 109 | jones \%in\% c(20:40) # TRUE 110 | match(jones, c(31:40)) # 3 111 | 112 | # Comparing a projects_author object to a character vector results in the 113 | # character strings being validated against the authors() table. Then, the id 114 | # numbers are compared. 115 | jones == c("jOnES", "hat") # TRUE FALSE 116 | 117 | ############################################################################# 118 | # Cleanup (or just restart R) 119 | Sys.setenv(HOME = old_home, PROJECTS_FOLDER_PATH = old_ppath) 120 | } 121 | \seealso{ 122 | \code{\link{Ops}}; \code{\link[methods]{Methods_for_Nongenerics}}. 123 | } 124 | -------------------------------------------------------------------------------- /man/projects_folder.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getters.R 3 | \name{projects_folder} 4 | \alias{projects_folder} 5 | \title{projects folder path} 6 | \usage{ 7 | projects_folder() 8 | } 9 | \description{ 10 | Returns the file path of the main projects folder if it has been established 11 | via \code{\link{setup_projects}()}. 12 | } 13 | \details{ 14 | The file path is returned as a simple character string. It simply returns the 15 | value of \code{\link{Sys.getenv}("PROJECTS_FOLDER_PATH")}, provided 16 | that its value is a file path of a directory that actually exists (i.e., 17 | \code{\link{setup_projects}()} has been successfully run). 18 | 19 | If it can't find a directory with that path, it returns this string: 20 | 21 | \code{projects folder not found. Please run \link{setup_projects}()} 22 | } 23 | \examples{ 24 | projects_folder() 25 | } 26 | \seealso{ 27 | \code{\link{setup_projects}()} for setting up the projects folder. 28 | } 29 | -------------------------------------------------------------------------------- /man/projects_stage-vctrs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class-projects_stage.R 3 | \name{vec_ptype2.projects_stage} 4 | \alias{vec_ptype2.projects_stage} 5 | \alias{vec_cast.projects_stage} 6 | \alias{projects_stage-vctrs} 7 | \title{Internal vctrs methods} 8 | \usage{ 9 | \method{vec_ptype2}{projects_stage}(x, y, ...) 10 | 11 | \method{vec_cast}{projects_stage}(x, to, ...) 12 | } 13 | \description{ 14 | Internal vctrs methods 15 | } 16 | \keyword{internal} 17 | -------------------------------------------------------------------------------- /man/projects_stage.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class-projects_stage.R 3 | \docType{class} 4 | \name{projects_stage} 5 | \alias{projects_stage} 6 | \alias{projects_stage-class} 7 | \alias{match.projects_stage} 8 | \alias{match,projects_stage,ANY-method} 9 | \alias{match,ANY,projects_stage-method} 10 | \alias{match,projects_stage,projects_stage-method} 11 | \alias{\%in\%.projects_stage} 12 | \alias{\%in\%,projects_stage-method} 13 | \title{\code{projects_stage} vector} 14 | \usage{ 15 | projects_stage(x = character()) 16 | 17 | match.projects_stage(x, table, nomatch = NA_integer_, incomparables = NULL) 18 | 19 | \S4method{match}{projects_stage,ANY}(x, table, nomatch = NA_integer_, incomparables = NULL) 20 | 21 | \S4method{match}{ANY,projects_stage}(x, table, nomatch = NA_integer_, incomparables = NULL) 22 | 23 | \S4method{match}{projects_stage,projects_stage}(x, table, nomatch = NA_integer_, incomparables = NULL) 24 | 25 | `\%in\%.projects_stage`(x, table) 26 | 27 | \S4method{\%in\%}{projects_stage}(x, table) 28 | } 29 | \arguments{ 30 | \item{x}{For \code{projects_stage()}, an integer or character vector. For 31 | 32 | For \code{\link{match}()} and \code{\link{\%in\%}}, an integer, a character 33 | string, or a \code{projects_stage} object. See \code{\link{match}()} and 34 | \strong{Comparison and value matching methods} below.} 35 | 36 | \item{table}{An integer number, a character string, or a 37 | \code{projects_stage} object. See \code{\link{match}()} and 38 | \strong{Comparison and value matching methods} below.} 39 | 40 | \item{nomatch}{See \code{\link{match}()}.} 41 | 42 | \item{incomparables}{An integer number, a character string, or a 43 | \code{projects_stage} object. See \code{\link{match}()}.} 44 | } 45 | \value{ 46 | For \code{projects_stage()}, an S3 vector of class 47 | \code{projects_stage}. 48 | } 49 | \description{ 50 | Objects of this class are merely a character string containing a number and a 51 | name of one of seven project development stages. 52 | } 53 | \details{ 54 | A \code{projects_stage} object is either a missing value (\code{NA}) or one 55 | of: 56 | 57 | \code{0: idea}\cr \code{1: design}\cr \code{2: data collection}\cr \code{3: 58 | analysis}\cr \code{4: manuscript}\cr \code{5: under review}\cr \code{6: 59 | accepted} 60 | 61 | \code{projects_stage()} validates and coerces a vector of the above integers or strings to a \code{projects_stage} S3 vector. 62 | } 63 | \section{Numeric coercion methods}{ 64 | \code{\link{as.integer}()}, 65 | \code{\link{as.double}()}, and \code{\link{as.numeric}()} return the stage 66 | number of the \code{projects_stage} object as an integer/double. The 67 | methods for the comparison and value matching functions described below 68 | make use of these numeric coercion methods. Users desiring to apply value 69 | matching functions other than the ones described below may similarly take 70 | advantage of these. 71 | } 72 | 73 | \section{Comparison and value matching methods}{ 74 | Methods for the 75 | \link{Comparison} operators as well as \code{\link{match}()} and 76 | \code{\link{\%in\%}} enable users to test equality and to value match among 77 | \code{projects_stage} objects and as well as between \code{projects_stage} 78 | objects and unclassed numbers/characters. When comparing or value matching 79 | against a numeric vector, the \code{projects_stage} object is first coerced 80 | to an integer with the \code{as.integer()} method described above. When 81 | testing or value matching against a character vector, the character vector 82 | is validated against the list of project stages enumerated above. 83 | } 84 | 85 | \examples{ 86 | stage <- projects_stage("4: manuscript") 87 | 88 | as.integer(stage) # 4 89 | 90 | stage == 4 # TRUE 91 | stage != 4 # FALSE 92 | stage < 6 # TRUE 93 | 94 | stage \%in\% c(3:6) # TRUE 95 | match(stage, 0:4) # 5 96 | 97 | stage \%in\% c("design", "manusc", "idea") # TRUE 98 | 99 | more_stages <- projects_stage(c("0: idea", "4: manuscript", "1: design")) 100 | 101 | match("MAnuscRIPT", more_stages) # 2 102 | } 103 | \seealso{ 104 | \code{\link{Ops}}; \code{\link[methods]{Methods_for_Nongenerics}}. 105 | } 106 | -------------------------------------------------------------------------------- /man/reordering.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/edit.R 3 | \name{reordering} 4 | \alias{reordering} 5 | \alias{reorder_authors} 6 | \alias{reorder_affiliations} 7 | \title{Reordering authors and affiliations} 8 | \usage{ 9 | reorder_authors(project, ..., after = 0L, archived = FALSE) 10 | 11 | reorder_affiliations(author, ..., after = 0L) 12 | } 13 | \arguments{ 14 | \item{project, author}{The \code{id} or unambiguous names of a project/author 15 | whose authors/affiliations you want to reorder.} 16 | 17 | \item{...}{The \code{id}s or names of authors/affiliations you want to 18 | reorder, optionally with their new ranks explicitly stated. See 19 | \strong{Details}.} 20 | 21 | \item{after}{If not specifying explicit ranks in \code{...}, the position you 22 | want the elements to come after. Works like the \code{after} argument in 23 | \code{\link[base]{append}} or 24 | \code{forcats::\link[forcats]{fct_relevel}()}. 25 | 26 | Ignored if ranks are explicitly provided in \code{...}.} 27 | 28 | \item{archived}{Logical indicating whether or not the function should 29 | consider archived projects when determining which project the user is 30 | referring to in the \code{project} argument. \code{FALSE} by default. 31 | 32 | See the \strong{Details} section of \code{\link{archive_project}()} for 33 | more information on the "archived" status of a project.} 34 | } 35 | \description{ 36 | These functions allow the user to reorder a project's authors or an author's 37 | affiliations. 38 | } 39 | \details{ 40 | The order of authors and affiliations affects the order in which these items 41 | appear in the output of \code{\link{header}()}. 42 | 43 | When specifying explicit ranks, enter \code{...} as name-value pairs (e.g., 44 | Johnson = 2, "Baron Cohen" = 4). You can even enumerate authors/affiliations 45 | by their corresponding (quoted) \code{id} numbers (e.g., `7` = 2, ACME = 4, 46 | `22` = 6). If entering an integer greater than the total number of 47 | authors/affiliations, the element will be put at the end. The \code{after} 48 | argument will be ignored in this case. 49 | 50 | When not specifying explicit ranks, simply enter author/affiliations 51 | \code{id}s or names in the order you want them, and the ones you entered will 52 | be inserted after the position specified by the \code{after} argument. By 53 | default (\code{after = 0}), the authors/affiliations in \code{...} will be 54 | moved to the front. This behavior corresponds to that of 55 | \code{\link{append}()} or \code{forcats::\link[forcats]{fct_relevel}()}. 56 | } 57 | \examples{ 58 | ############################################################################# 59 | # SETUP 60 | old_home <- Sys.getenv("HOME") 61 | old_ppath <- Sys.getenv("PROJECTS_FOLDER_PATH") 62 | temp_dir <- tempfile("dir") 63 | dir.create(temp_dir) 64 | Sys.unsetenv("PROJECTS_FOLDER_PATH") 65 | Sys.setenv(HOME = temp_dir) 66 | setup_projects(path = temp_dir) 67 | new_affiliation(department_name = "Math Dept.", 68 | institution_name = "Springfield College", 69 | address = "123 College St, Springfield, AB") 70 | new_affiliation(department_name = "Art Department", 71 | institution_name = "Springfield College", 72 | address = "321 University Boulevard, Springfield, AB", 73 | id = 42) 74 | new_affiliation(department_name = "Central Intelligence Agency", 75 | institution_name = "United States Government", 76 | address = "888 Classified Dr, Washington DC") 77 | new_affiliation(department_name = "Pyrotechnics", 78 | institution_name = "ACME") 79 | new_author(given_names = "Rosetta", last_name = "Stone", 80 | affiliations = c(42, "Math"), degree = "PhD", 81 | email = "slab@rock.net", phone = "867-555-5309", id = 8888) 82 | new_author(given_names = "Spiro", last_name = "Agnew", degree = "LLB", 83 | affiliations = "Art D", id = 13) 84 | new_author(given_names = "Plato", id = 303) 85 | new_author(given_names = "Condoleezza", last_name = "Rice", degree = "PhD", 86 | affiliations = c(1, 42, "Agency", "ACME"), phone = "555-555-5555", 87 | email = "condoleeza@ri.ce") 88 | new_author(given_names = "Jane", last_name = "Goodall", degree = "PhD", 89 | affiliations = 3, id = 5) 90 | new_project(title = "Understanding the Construction of the United States", 91 | short_title = "USA", 92 | authors = c(13, "Stone", "zz", "303", "Jane Goodall"), 93 | stage = 4, deadline = "2055-02-28", deadline_type = "submission", 94 | parent_directory = "famous_studied/philosophers/rocks", 95 | corresp_auth = "Stone", current_owner = "agnew", 96 | make_directories = TRUE, 97 | status = "waiting on IRB") 98 | ############################################################################# 99 | 100 | # Rice's affiliations before reordering: 101 | authors("rice", affiliations = TRUE) 102 | 103 | # Reordering (with unnamed arguments) 104 | reorder_affiliations(author = "RICE", "ACME", 42, after = 1) 105 | 106 | # Rice's affiliations after reordering: 107 | authors("rice", affiliations = TRUE) 108 | 109 | # Project 1 header before reordering authors: 110 | header(1) 111 | 112 | # Reordering (with named arguments) 113 | reorder_authors(project = 1, "Rosetta" = 99, `303` = 2, "5" = 1) 114 | 115 | # Project 1 header after reordering authors: 116 | header(1) 117 | 118 | ############################################################################# 119 | # CLEANUP 120 | Sys.setenv(HOME = old_home, PROJECTS_FOLDER_PATH = old_ppath) 121 | } 122 | -------------------------------------------------------------------------------- /man/save_session_info.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/reproducibility.R 3 | \name{save_session_info} 4 | \alias{save_session_info} 5 | \title{Save R session information} 6 | \usage{ 7 | save_session_info(path_dir = here::here("progs", "session_info")) 8 | } 9 | \arguments{ 10 | \item{path_dir}{The full path of the directory where the session information 11 | text file shall be written. If it doesn't exist, it is written with 12 | \code{fs::\link[fs]{dir_create}()}.} 13 | } 14 | \value{ 15 | A list of two: 16 | 17 | \code{$ time :} the value of \code{\link{Sys.time}()} that the 18 | function used 19 | 20 | \code{$ session_info() :} the value of 21 | \code{sessioninfo::\link[sessioninfo]{session_info}()} that the function 22 | used 23 | } 24 | \description{ 25 | Creates a dated text file (.txt) containing the contents of 26 | \code{sessioninfo::\link[sessioninfo]{session_info}()}. 27 | } 28 | \details{ 29 | The date and time when this function was run is included in the resulting 30 | .txt file's name and first line. This date and time is obtained from 31 | \code{\link{Sys.time}()}. 32 | 33 | For the file name, hyphens (-) are removed from the date, spaces are replaced 34 | with underscores (_), and colons (:) are replaced with a modifier letter 35 | colon (U+A789). 36 | } 37 | -------------------------------------------------------------------------------- /man/setup_projects.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/setup.R 3 | \name{setup_projects} 4 | \alias{setup_projects} 5 | \title{Set up the projects folder} 6 | \usage{ 7 | setup_projects( 8 | path, 9 | folder_name = "projects", 10 | overwrite = FALSE, 11 | make_directories = FALSE, 12 | .Renviron_path = file.path(Sys.getenv("HOME"), ".Renviron") 13 | ) 14 | } 15 | \arguments{ 16 | \item{path}{The file path of the \strong{directory inside of which} the user 17 | would like the projects folder to be created. Do not include the name of 18 | the projects folder itself (i.e., the value of the argument 19 | \code{folder_name} below).} 20 | 21 | \item{folder_name}{The name of the projects folder that will be created in 22 | the directory specified by the argument \code{path} above. Defaults to 23 | \code{"projects"}.} 24 | 25 | \item{overwrite}{Logical indicating whether or not to abandon any previously 26 | stored projects folders stored in the system.} 27 | 28 | \item{make_directories}{Logical indicating whether or not the function should 29 | write any directories specified in the \code{path} argument that don't 30 | already exist.} 31 | 32 | \item{.Renviron_path}{The full file path of the .Renviron file where the user 33 | would like to store the \code{\link{projects_folder}()} path. Default is 34 | the home .Renviron file. If the file doesn't exist it will be created.} 35 | } 36 | \value{ 37 | The project folder's path, invisibly. 38 | } 39 | \description{ 40 | Creates or restores the projects folder at the user-specified path. 41 | } 42 | \details{ 43 | The \code{\link[=projects-package]{projects}} package remembers where the 44 | \link[=projects_folder]{projects folder} is located by storing its file path 45 | in a \link{.Renviron} file (the home .Renviron file by default). The entry is 46 | named \code{PROJECTS_FOLDER_PATH}. 47 | 48 | Note that changing the \code{.Renviron_path} argument may create an .Renviron 49 | file that R will not notice or use. See \link{Startup} for more details. 50 | } 51 | \section{Default contents}{ 52 | The \link[=projects_folder]{projects folder} 53 | automatically contains the subdirectories \emph{.metadata} and 54 | \emph{.templates}, which are hidden by default on some operating systems. 55 | 56 | The \emph{.metadata} folder and its contents should \strong{never} be 57 | manually moved or modified. 58 | 59 | The \emph{.templates} folder is where template project files and folders 60 | should be stored. When this function is successfully run, the default 61 | projects folder template is created (as "default_folder") alongside a few 62 | other template files. When a new project is created, 63 | \code{\link{new_project}()} looks here for the folder named by its 64 | \code{template_folder} argument (\code{"default_folder"} by default), and 65 | this folder is copied into the \link[=projects_folder]{projects folder} 66 | (with name specified by the \code{folder_name} argument) as the new project 67 | folder. Users are able and encouraged to customize the 68 | \code{default_folder} to suit their research needs, and may even create 69 | multiple project folder templates for different situations. 70 | 71 | The default templates are in the folder located at the path produced by 72 | running: \code{\link{system.file}("templates", package = "projects")} 73 | } 74 | 75 | \section{Behavior when projects folder already exists}{ 76 | If \code{overwrite = 77 | TRUE}, the function will run no matter what. Use with caution. 78 | 79 | If the user has a pre-existing \link[=projects_folder]{projects folder} and 80 | runs this command with the pre-existing projects folder's path, nothing 81 | will be deleted. 82 | 83 | \strong{Therefore}, if the user "broke" the projects folder (e.g., by 84 | deleting metadata; by changing the "PROJECTS_FOLDER_PATH" line in the 85 | \emph{.Renviron} file), the user can "fix" the projects folder to some 86 | degree by running this function with the folder's actual file path (e.g., 87 | restore all default templates; restore missing metadata files). 88 | } 89 | 90 | \examples{ 91 | ############################################################################# 92 | # Setup 93 | # Any existing "projects" folder is left totally untouched, 94 | # and the user's home directory and .Renviron file are also left untouched. 95 | old_home <- Sys.getenv("HOME") 96 | old_ppath <- Sys.getenv("PROJECTS_FOLDER_PATH") 97 | temp_dir <- tempfile("dir") 98 | dir.create(temp_dir) 99 | Sys.setenv(HOME = temp_dir) 100 | Sys.unsetenv("PROJECTS_FOLDER_PATH") 101 | ############################################################################# 102 | 103 | # Creating the projects folder 104 | setup_projects(path = temp_dir) 105 | 106 | # Viewing the projects folder path: 107 | path1 <- projects_folder() 108 | 109 | # Viewing the contents of the projects folder: 110 | list.files(path1, full.names = TRUE, recursive = TRUE, all.files = TRUE) 111 | 112 | # Create an arbitrary subfolder in temp_dir: 113 | subfolder_path <- file.path(temp_dir, "test") 114 | dir.create(subfolder_path) 115 | 116 | 117 | # Wrapped in if (interactive()) because it requires user input 118 | if (interactive()) { 119 | # The function won't let the user abandon the old projects folder... 120 | setup_projects(path = subfolder_path) 121 | 122 | # ...unless overwrite = TRUE 123 | setup_projects(path = file.path(temp_dir, "test"), overwrite = TRUE) 124 | 125 | # Even then, only the stored location of the projects folder is overwritten. 126 | # The old projects folder still exists: 127 | list.files(path1, full.names = TRUE, recursive = TRUE, all.files = TRUE) 128 | 129 | # Giving the "projects" folder a different name: 130 | setup_projects(path = temp_dir, folder_name = "studies", overwrite = TRUE) 131 | } 132 | 133 | ############################################################################# 134 | # Cleanup 135 | # (or, the user can just restart R) 136 | Sys.setenv(HOME = old_home, PROJECTS_FOLDER_PATH = old_ppath) 137 | ############################################################################# 138 | } 139 | \seealso{ 140 | \code{\link{new_project}()} for information on templates 141 | 142 | \link{Startup} for more information on how \emph{.Renviron} files work. 143 | } 144 | -------------------------------------------------------------------------------- /man/update_metadata.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/update.R 3 | \name{update_metadata} 4 | \alias{update_metadata} 5 | \title{Update the project metadata} 6 | \usage{ 7 | update_metadata(ask = TRUE) 8 | } 9 | \arguments{ 10 | \item{ask}{Logical, indicating whether or not the user would be asked at the 11 | command line whether or not to proceed. Defaults to \code{TRUE}.} 12 | } 13 | \description{ 14 | Safely updates existing project metadata to be compatible with 15 | \code{\link[=projects-package]{projects}} 1.X.X. 16 | } 17 | \details{ 18 | Prior to \code{\link[=projects-package]{projects}} 1.X.X, the \code{stage}, 19 | \code{current_owner}, \code{corresp_auth}, and \code{creator} columns of the 20 | \code{\link{projects}()} table were different. 21 | 22 | The \code{stage} column was a \link{factor}, and users had to type stage 23 | names exactly, down to the integer, colon, and space. Now, this column is of 24 | class \code{\link{projects_stage-class}}. 25 | 26 | The latter three columns were integers corresponding to \code{id}s in the 27 | \code{\link{authors}()} table, so users would have to query that table if 28 | they did not remember which author was denoted by the integer \code{id}. 29 | } 30 | \seealso{ 31 | \code{\link{projects_stage-class}}; 32 | \code{\link{projects_author-class}}. 33 | } 34 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(projects) 3 | 4 | test_check("projects") 5 | -------------------------------------------------------------------------------- /tests/testthat/test-setup.R: -------------------------------------------------------------------------------- 1 | test_that("Everything works", { 2 | 3 | old_home <- Sys.getenv("HOME") 4 | old_ppath <- Sys.getenv("PROJECTS_FOLDER_PATH") 5 | temp_dir <- tempfile("dir") 6 | dir.create(temp_dir) 7 | Sys.setenv(HOME = temp_dir) 8 | Sys.unsetenv("PROJECTS_FOLDER_PATH") 9 | 10 | expect_equal( 11 | fs::path_tidy(setup_projects(temp_dir)), 12 | fs::path_tidy(fs::path(temp_dir, "projects")) 13 | ) 14 | 15 | expect_message( 16 | setup_projects(temp_dir, folder_name = "projects2"), 17 | "\nThe environment variable PROJECTS_FOLDER_PATH indicates" 18 | ) 19 | 20 | expect_equal( 21 | sort(fs::dir_ls(projects_folder(), all = TRUE, recurse = TRUE)), 22 | sort( 23 | fs::path( 24 | projects_folder(), 25 | c( 26 | ".metadata", 27 | ".metadata/affiliations.rds", 28 | ".metadata/author_affiliation_assoc.rds", 29 | ".metadata/authors.rds", 30 | ".metadata/project_author_assoc.rds", 31 | ".metadata/projects.rds", 32 | ".metadata/tasks.rds", 33 | ".templates", 34 | ".templates/CONSORT_protocol.Rmd", 35 | ".templates/STROBE_protocol.Rmd", 36 | ".templates/default_folder", 37 | ".templates/default_folder/data", 38 | ".templates/default_folder/data_raw", 39 | ".templates/default_folder/figures", 40 | ".templates/default_folder/manuscript", 41 | ".templates/default_folder/pXXXX.Rproj", 42 | ".templates/default_folder/progs", 43 | ".templates/default_folder/progs/01_protocol.Rmd", 44 | ".templates/default_folder/progs/02_datawork.Rmd", 45 | ".templates/default_folder/progs/03_analysis.Rmd", 46 | ".templates/default_folder/progs/04_report.Rmd", 47 | ".templates/default_folder/progs/citations.bib", 48 | ".templates/default_folder/progs/style.css", 49 | ".templates/default_folder/progs/styles.docx" 50 | ) 51 | ) 52 | ), 53 | ignore_attr = "names" 54 | ) 55 | 56 | expect_error( 57 | new_affiliation( 58 | department_name = "Math Dept.", 59 | institution_name = "Springfield College", 60 | address = "123 College St, Springfield, AB" 61 | ), 62 | NA 63 | ) 64 | 65 | expect_error( 66 | new_affiliation( 67 | department_name = "Art Department", 68 | institution_name = "Springfield College", 69 | address = "321 University Boulevard, Springfield, AB", 70 | id = 42 71 | ), 72 | NA 73 | ) 74 | 75 | expect_error( 76 | edit_affiliation("Math Dept", department_name = "Mathematics Department"), 77 | NA 78 | ) 79 | 80 | expect_error( 81 | new_author( 82 | given_names = "Rosetta", 83 | last_name = "Stone", 84 | affiliations = c(42, "Math"), 85 | degree = "PhD", 86 | email = "slab@rock.net", 87 | phone = "867-555-5309", 88 | id = 8888 89 | ), 90 | NA 91 | ) 92 | 93 | expect_error( 94 | new_author(id = 8888, given_names = "Johhhhhn") 95 | ) 96 | 97 | expect_error( 98 | new_author( 99 | given_names = "Spiro", 100 | last_name = "Agnew", 101 | degree = "LLB", 102 | affiliations = "Art D", 103 | id = 13 104 | ), 105 | NA 106 | ) 107 | 108 | expect_error( 109 | new_author(given_names = "Plato", id = 303), 110 | NA 111 | ) 112 | 113 | expect_error( 114 | edit_author( 115 | author = 303, 116 | given_names = NA, 117 | last_name = "Plato", 118 | title = "Nut" 119 | ), 120 | NA 121 | ) 122 | 123 | expect_error( 124 | edit_author("Spiro", affiliations = ~ -"Art D" + Math), 125 | NA 126 | ) 127 | 128 | 129 | expect_error( 130 | new_project( 131 | title = "Understanding the Construction of the United States", 132 | short_title = "USA", 133 | authors = c(13, "Stone"), 134 | stage = 4, 135 | deadline = "2055-02-28", 136 | deadline_type = "submission", 137 | parent_directory = "famous_studied/philosophers/rocks", 138 | corresp_auth = "Stone", 139 | current_owner = "agnew", 140 | make_directories = TRUE, 141 | status = "waiting on IRB" 142 | ), 143 | NA 144 | ) 145 | 146 | 147 | expect_error( 148 | edit_project( 149 | "Understanding", 150 | short_title = "usa1", 151 | authors = ~ + "303" - Stone, 152 | corresp_auth = "plato", 153 | impact = Inf 154 | ), 155 | NA 156 | ) 157 | 158 | expect_error( 159 | new_idea(title = "Boiling the Ocean", impact = pi), 160 | NA 161 | ) 162 | 163 | expect_identical( 164 | affiliations(), 165 | dplyr::tribble( 166 | ~id, ~department_name, ~institution_name, ~address, 167 | 1L, "Mathematics Department", "Springfield College", "123 College St, Springfield, AB", 168 | 42L, "Art Department", "Springfield College", "321 University Boulevard, Springfield, AB" 169 | ) %>% structure(class = c("projects_metadata_tbl", class(.))) 170 | ) 171 | 172 | expect_identical( 173 | authors(), 174 | dplyr::tribble( 175 | ~id, ~last_name, ~given_names, ~title, ~degree, ~email, ~phone, 176 | 13L, "Agnew", "Spiro", NA, "LLB", NA, NA, 177 | 303L, "Plato", NA, "Nut", NA, NA, NA, 178 | 8888L, "Stone", "Rosetta", NA, "PhD", "slab@rock.net", "867-555-5309" 179 | ) %>% structure(class = c("projects_metadata_tbl", class(.))) 180 | ) 181 | 182 | expect_identical( 183 | projects(verbose = TRUE, all_stages = TRUE), 184 | dplyr::tibble( 185 | id = 1L:2L, 186 | title = c("Understanding the Construction of the United States", 187 | "Boiling the Ocean"), 188 | short_title = c("usa1", NA), 189 | current_owner = new_projects_author(c("13: Agnew", NA)), 190 | status = c("waiting on IRB", "just an idea"), 191 | deadline_type = c("submission", NA), 192 | deadline = lubridate::as_datetime(c("2055-02-28", NA)), 193 | stage = new_projects_stage(c("4: manuscript", "0: idea")), 194 | impact = c(Inf, pi), 195 | path = unclass(c(fs::path(projects_folder(), 196 | "famous_studied/philosophers/rocks/p0001"), 197 | fs::path(projects_folder(), "p0002"))), 198 | corresp_auth = new_projects_author(c("303: Plato", NA)), 199 | creator = new_projects_author(rep(paste0("0: ", Sys.info()["user"]), 2L)) 200 | ) %>% structure(class = c("projects_metadata_tbl", class(.))) 201 | ) 202 | 203 | expect_identical( 204 | get_rds(make_rds_path("project_author_assoc")), 205 | dplyr::tibble(id1 = c(1L, 1L), id2 = c(13L, 303L)) 206 | ) 207 | 208 | expect_identical( 209 | get_rds(make_rds_path("author_affiliation_assoc")), 210 | dplyr::tibble(id1 = c(8888L, 8888L, 13L), id2 = c(42L, 1L, 1L)) 211 | ) 212 | 213 | expect_error( 214 | new_task(project = 2, 215 | task = "put the horse before the cart", 216 | lead = "spiro", 217 | timing = NaN), 218 | NA 219 | ) 220 | 221 | expect_error( 222 | new_task(project = 1, 223 | task = "learn something", 224 | effort = pi, 225 | lead = "Stone", 226 | status = "foobar", 227 | timing = Inf), 228 | NA 229 | ) 230 | 231 | expect_error( 232 | new_task(project = 1, 233 | task = "take a break", 234 | TID = 600.66, 235 | effort = -100, 236 | status = "throw it all away", 237 | lead = "303"), 238 | NA 239 | ) 240 | 241 | expect_error( 242 | new_task( 243 | project = 1, 244 | task = "tie your shoes", 245 | TID = 2, 246 | lead = 303), 247 | NA 248 | ) 249 | 250 | expect_error( 251 | new_task( 252 | project = 1, 253 | task = "put out the fire", 254 | TID = .5, 255 | lead = "stone"), 256 | NA 257 | ) 258 | 259 | expect_error( 260 | edit_task( 261 | project = "understanding", 262 | TID = 3, 263 | new_TID = 2, 264 | lead = "agnew", 265 | done = 1, 266 | effort = 77L, 267 | status = "make dinner" 268 | ), 269 | NA 270 | ) 271 | 272 | expect_equal( 273 | tasks(), 274 | dplyr::tibble( 275 | PID = c(1, 1, 1, 1, 2), 276 | project = c(rep("Understanding the Construction of the United States", 4), "Boiling the Ocean"), 277 | PI = new_projects_author(c(rep("303: Plato", 4), NA)), 278 | impact = c(rep(Inf, 4), pi), 279 | TID = c(1, 2, 3, 4, 1), 280 | done = c(0, 1, 0, 0, 0), 281 | task = c("put out the fire", "tie your shoes", "learn something", "take a break", "put the horse before the cart"), 282 | effort = c(NA, 77, pi, -100, NA), 283 | timing = c(NA, NA, Inf, NA, NaN), 284 | lead = new_projects_author(c("8888: Stone", "13: Agnew", "8888: Stone", "303: Plato", "13: Agnew")), 285 | status = c(NA, "make dinner", "foobar", "throw it all away", NA) 286 | ) 287 | ) 288 | 289 | finish("construction", 4) 290 | 291 | expect_equal( 292 | tasks("construction", c(13, "plato")), 293 | dplyr::tibble( 294 | PID = c(1, 1), 295 | project = rep("Understanding the Construction of the United States", 2), 296 | PI = new_projects_author(rep("303: Plato", 2)), 297 | impact = c(Inf, Inf), 298 | TID = c(2, 4), 299 | done = c(1, 1), 300 | task = c("tie your shoes", "take a break"), 301 | effort = c(77, -100), 302 | timing = rep(NA_real_, 2), 303 | lead = new_projects_author(c("13: Agnew", "303: Plato")), 304 | status = c("make dinner", "throw it all away") 305 | ) 306 | ) 307 | 308 | Sys.setenv(HOME = old_home, PROJECTS_FOLDER_PATH = old_ppath) 309 | }) 310 | --------------------------------------------------------------------------------