├── .github ├── .gitignore └── workflows │ └── render_readme.yaml ├── .Rprofile ├── .Rbuildignore ├── renv ├── .gitignore ├── settings.dcf └── activate.R ├── .gitignore ├── awesome-nhsr.Rproj ├── LICENSE ├── Readme.Rmd ├── Readme.md └── renv.lock /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.Rprofile: -------------------------------------------------------------------------------- 1 | source("renv/activate.R") 2 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^renv$ 2 | ^renv\.lock$ 3 | ^\.github$ 4 | -------------------------------------------------------------------------------- /renv/.gitignore: -------------------------------------------------------------------------------- 1 | library/ 2 | local/ 3 | cellar/ 4 | lock/ 5 | python/ 6 | staging/ 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | .Rproj 6 | nhsr-helpful-packages.Rproj 7 | -------------------------------------------------------------------------------- /renv/settings.dcf: -------------------------------------------------------------------------------- 1 | bioconductor.version: 2 | external.libraries: 3 | ignored.packages: 4 | package.dependency.fields: Imports, Depends, LinkingTo 5 | r.version: 6 | snapshot.type: implicit 7 | use.cache: TRUE 8 | vcs.ignore.cellar: TRUE 9 | vcs.ignore.library: TRUE 10 | vcs.ignore.local: TRUE 11 | -------------------------------------------------------------------------------- /awesome-nhsr.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 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | -------------------------------------------------------------------------------- /.github/workflows/render_readme.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | issues: 3 | types: [labeled] 4 | 5 | name: Render readme and create a PR 6 | 7 | jobs: 8 | render_readme: 9 | runs-on: ubuntu-latest 10 | if: github.event.label.name == 'airtable-update' 11 | env: 12 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 13 | AIRTABLE_API_KEY: ${{ secrets.AIRTABLE_API_KEY }} 14 | AIRTABLE_BASE: ${{ secrets.AIRTABLE_BASE }} 15 | steps: 16 | - uses: actions/checkout@v2 17 | 18 | - uses: r-lib/actions/setup-pandoc@v1 19 | 20 | - uses: r-lib/actions/setup-r@v1 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: tomjemmett/renv-install-system-deps@v1 25 | 26 | - uses: r-lib/actions/setup-renv@v1 27 | 28 | - name: Build Readme 29 | run: Rscript -e 'rmarkdown::render("Readme.Rmd")' 30 | 31 | - name: Create Pull Request 32 | uses: peter-evans/create-pull-request@v4 33 | with: 34 | add-paths: Readme.md 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /Readme.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "NHS-R Recommended packages" 3 | output: github_document 4 | --- 5 | 6 | ```{r setup, include=FALSE, echo=FALSE, message=FALSE} 7 | knitr::opts_chunk$set(echo = TRUE) 8 | library(tidyverse) 9 | library(janitor) 10 | library(airtabler) 11 | 12 | # a dataframe is imported from the Airtable base using the airtabler package and the Airtable API 13 | nhsrpack <- airtable(base = Sys.getenv("AIRTABLE_BASE"), tables = c("packages")) 14 | 15 | packages <- nhsrpack$packages$select() %>% 16 | clean_names() 17 | 18 | ``` 19 | 20 | Below you will find packages recommended by members of the NHS-R community. These have been grouped by the type of package and how it is typically applied in data analysis. 21 | 22 | In addition there are some links to useful scripts, websites and resources for other languages at the end of the document. 23 | 24 | If you would like to suggest a package that you use in your role in the NHS. Please consider filling in [this form](https://airtable.com/shr7xXh4KJpAKzvZ8) so we can add the resource to the page. 25 | Alternatively join the [NHS-R slack channel](nhsrcommunity.slack.com) and add your recommendation as a post in the packages channel. 26 | 27 | ## Data visualisation 28 | 29 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 30 | 31 | # This function repeats for each sub section of the readme. 32 | # Packages data frame is split by category which is a field in the database 33 | # packages are ordered alphabetically and then the data frame is split by each package 34 | # using purr the variables within the data frames are accessed using '.$x' and printed using cat() 35 | # each r chunk outputs markdown due to the chunk option results='asis' 36 | 37 | invisible(packages %>% 38 | filter(category=='Data visualisation') %>% 39 | arrange(package_name) %>% 40 | group_split(package_name) %>% 41 | purrr::imap(.,~{ 42 | cat("###", .$package_name, "\n") 43 | cat("\n") 44 | cat(.$package_function, "\n") 45 | cat("\n") 46 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 47 | cat("\n") 48 | cat("\n") 49 | }) 50 | ) 51 | 52 | ``` 53 | 54 | 55 | --- 56 | 57 | ## Data wrangling 58 | 59 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 60 | invisible(packages %>% 61 | filter(category=='Data wrangling') %>% 62 | arrange(package_name) %>% 63 | group_split(package_name) %>% 64 | purrr::imap(.,~{ 65 | cat("###", .$package_name, "\n") 66 | cat("\n") 67 | cat(.$package_function, "\n") 68 | cat("\n") 69 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 70 | cat("\n") 71 | cat("\n") 72 | }) 73 | ) 74 | ``` 75 | 76 | 77 | --- 78 | 79 | ## Database 80 | 81 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 82 | invisible(packages %>% 83 | filter(category=='Database') %>% 84 | arrange(package_name) %>% 85 | group_split(package_name) %>% 86 | purrr::imap(.,~{ 87 | cat("###", .$package_name, "\n") 88 | cat("\n") 89 | cat(.$package_function, "\n") 90 | cat("\n") 91 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 92 | cat("\n") 93 | cat("\n") 94 | cat("\n") 95 | }) 96 | ) 97 | ``` 98 | 99 | 100 | --- 101 | 102 | ## Hospital Coding 103 | 104 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 105 | invisible(packages %>% 106 | filter(category=='Hospital Coding') %>% 107 | arrange(package_name) %>% 108 | group_split(package_name) %>% 109 | purrr::imap(.,~{ 110 | cat("###", .$package_name, "\n") 111 | cat("\n") 112 | cat(.$package_function, "\n") 113 | cat("\n") 114 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 115 | cat("\n") 116 | cat("\n") 117 | cat("\n") 118 | }) 119 | ) 120 | ``` 121 | 122 | 123 | --- 124 | 125 | ## Modelling 126 | 127 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 128 | invisible(packages %>% 129 | filter(category=='Modelling') %>% 130 | arrange(package_name) %>% 131 | group_split(package_name) %>% 132 | purrr::imap(.,~{ 133 | cat("###", .$package_name, "\n") 134 | cat("\n") 135 | cat(.$package_function, "\n") 136 | cat("\n") 137 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 138 | cat("\n") 139 | cat("\n") 140 | cat("\n") 141 | }) 142 | ) 143 | ``` 144 | 145 | 146 | --- 147 | 148 | ## Reproducibility 149 | 150 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 151 | invisible(packages %>% 152 | filter(category=='Reproducibility') %>% 153 | arrange(package_name) %>% 154 | group_split(package_name) %>% 155 | purrr::imap(.,~{ 156 | cat("###", .$package_name, "\n") 157 | cat("\n") 158 | cat(.$package_function, "\n") 159 | cat("\n") 160 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 161 | cat("\n") 162 | cat("\n") 163 | cat("\n") 164 | }) 165 | ) 166 | ``` 167 | 168 | 169 | --- 170 | 171 | ## External data resource 172 | 173 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 174 | invisible(packages %>% 175 | filter(category=='External data resource') %>% 176 | arrange(package_name) %>% 177 | group_split(package_name) %>% 178 | purrr::imap(.,~{ 179 | cat("###", .$package_name, "\n") 180 | cat("\n") 181 | cat(.$package_function, "\n") 182 | cat("\n") 183 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 184 | cat("\n") 185 | cat("\n") 186 | cat("\n") 187 | }) 188 | ) 189 | ``` 190 | 191 | 192 | --- 193 | 194 | ## R Development 195 | 196 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 197 | invisible(packages %>% 198 | filter(category=='R Development') %>% 199 | arrange(package_name) %>% 200 | group_split(package_name) %>% 201 | purrr::imap(.,~{ 202 | cat("###", .$package_name, "\n") 203 | cat("\n") 204 | cat(.$package_function, "\n") 205 | cat("\n") 206 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 207 | cat("\n") 208 | cat("\n") 209 | cat("\n") 210 | }) 211 | ) 212 | ``` 213 | 214 | 215 | --- 216 | 217 | ## Rstudio Plugin 218 | 219 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 220 | invisible(packages %>% 221 | filter(category=='Rstudio Plugin') %>% 222 | arrange(package_name) %>% 223 | group_split(package_name) %>% 224 | purrr::imap(.,~{ 225 | cat("###", .$package_name, "\n") 226 | cat("\n") 227 | cat(.$package_function, "\n") 228 | cat("\n") 229 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 230 | cat("\n") 231 | cat("\n") 232 | cat("\n") 233 | }) 234 | ) 235 | ``` 236 | 237 | 238 | --- 239 | 240 | ## Rscript or function 241 | 242 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 243 | invisible(packages %>% 244 | filter(category=='Rscript or function') %>% 245 | arrange(package_name) %>% 246 | group_split(package_name) %>% 247 | purrr::imap(.,~{ 248 | cat("###", .$package_name, "\n") 249 | cat("\n") 250 | cat(.$package_function, "\n") 251 | cat("\n") 252 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 253 | cat("\n") 254 | cat("\n") 255 | cat("\n") 256 | }) 257 | ) 258 | ``` 259 | 260 | 261 | --- 262 | 263 | ## Links 264 | 265 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 266 | invisible(packages %>% 267 | filter(category=='Link') %>% 268 | arrange(package_name) %>% 269 | group_split(package_name) %>% 270 | purrr::imap(.,~{ 271 | cat("###", .$package_name, "\n") 272 | cat("\n") 273 | cat(.$package_function, "\n") 274 | cat("\n") 275 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 276 | cat("\n") 277 | cat("\n") 278 | cat("\n") 279 | }) 280 | ) 281 | ``` 282 | 283 | --- 284 | 285 | ## Resources in other languages 286 | 287 | ```{r, include=TRUE, echo=FALSE, results='asis', message=FALSE} 288 | invisible(packages %>% 289 | filter(category=='Resources in other languages') %>% 290 | arrange(package_name) %>% 291 | group_split(package_name) %>% 292 | purrr::imap(.,~{ 293 | cat("###", .$package_name, "\n") 294 | cat("\n") 295 | cat(.$package_function, "\n") 296 | cat("\n") 297 | cat( '[','GitHub url',']','(',.$git_hub,')', "\n", sep = '') 298 | cat("\n") 299 | cat("\n") 300 | cat("\n") 301 | }) 302 | ) 303 | ``` 304 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | NHS-R Recommended packages 2 | ================ 3 | 4 | Below you will find packages recommended by members of the NHS-R 5 | community. These have been grouped by the type of package and how it is 6 | typically applied in data analysis. 7 | 8 | In addition there are some links to useful scripts, websites and 9 | resources for other languages at the end of the document. 10 | 11 | If you would like to suggest a package that you use in your role in the 12 | NHS. Please consider filling in [this 13 | form](https://airtable.com/shr7xXh4KJpAKzvZ8) so we can add the resource 14 | to the page. 15 | Alternatively join the [NHS-R slack channel](nhsrcommunity.slack.com) 16 | and add your recommendation as a post in the packages channel. 17 | 18 | ## Data visualisation 19 | 20 | ### Cumsumcharter 21 | 22 | The goal of cusumcharter is to create both simple CUSUM charts, with and 23 | without control limits from a vector, or to create multiple CUSUM 24 | charts, with or without control limits, from a grouped dataframe, tibble 25 | or data.table. 26 | 27 | CUSUM charts detect small changes over time, and will alert quicker than 28 | a Statistical Process Control chart. They are an excellent alternative 29 | to run and control charts, particularly where data is scarce, 30 | infrequent, or expensive to obtain. 31 | 32 | They monitor the difference between each data point, relative to a 33 | target value, which is often the mean of all the currently available 34 | data points. Using these variances and targets, control limits are 35 | calculated. Any points outside these limits are an indication that the 36 | process is out of control. 37 | 38 | [GitHub url](https://github.com/johnmackintosh/cusumcharter) 39 | 40 | ### ddplot 41 | 42 | Create D3 based SVG graphics using a simple R Api 43 | 44 | [GitHub url](https://feddelegrand7.github.io/ddplot/) 45 | 46 | ### MetBrewer 47 | 48 | Palettes inspired by works at the Metropolitan Museum of Art in New 49 | York. Pieces selected come from various time periods, regions, and 50 | mediums. 51 | 52 | [GitHub url](https://github.com/BlakeRMills/MetBrewer/tree/main) 53 | 54 | ### Orgcharter 55 | 56 | The goal of orgcharter is to help make simple organisation charts, to 57 | help you communicate your organisation’s structure to those who need to 58 | understand it. Often, that is the people who work within it\! 59 | 60 | This package is a convenient wrapper around the {DiagrammeR} package. If 61 | you are interested in understanding more or extending this package, that 62 | is a very good place to start. 63 | 64 | [GitHub url](https://github.com/ThomUK/orgcharter) 65 | 66 | ### runcharter 67 | 68 | Plots multiple run charts, finds successive signals of improvement, and 69 | revises medians when each signal occurs. Finds runs above, below, or on 70 | both sides of the median, and returns a plot and a data.table 71 | summarising original medians and any revisions, for all groups within 72 | the supplied data. 73 | 74 | [GitHub url](https://github.com/johnmackintosh/runcharter) 75 | 76 | ### simplevis 77 | 78 | simplevis is a package of ggplot2 and leaflet wrapper functions that 79 | aims to make visualisation easier with less brainpower required. 80 | 81 | [GitHub url](https://statisticsnz.github.io/simplevis) 82 | 83 | ----- 84 | 85 | ## Data wrangling 86 | 87 | ### NHS-MSDS-pipeline 88 | 89 | Automatically download, join, and clean the NHS Digital Maternity 90 | Services Monthly Statistics data (MSMS), which is derived from the 91 | Maternity Services Data Set (MSDS). When new information is released by 92 | NHS Digital, re-running the scripts will add the new information to your 93 | downloaded data, allowing analysis on the full dataset. 94 | 95 | [GitHub url](https://github.com/ThomUK/NHS-MSDS-pipeline) 96 | 97 | ### numberwang 98 | 99 | numberwang will convert floating point numbers (and integers) to their 100 | word representations, and vice versa. 101 | 102 | The key differentiator of this package, compared to {nombre}, is that it 103 | supports decimal representations by listing individual decimal digits. 104 | 105 | [GitHub url](https://github.com/coolbutuseless/numberwang) 106 | 107 | ### padr 108 | 109 | padr is an R package that assists with preparing time series data. It 110 | provides two main functions that will quickly get the data in the format 111 | you want. When data is observed on too low a level, thicken will add a 112 | column of a higher interval to the data frame, after which the user can 113 | apply the appropriate aggregation. When there are missing records for 114 | time points where observations were absent, pad will automatically 115 | insert these records. A number of fill\_ functions help to subsequently 116 | fill the missing values. 117 | 118 | [GitHub url](https://github.com/EdwinTh/padr) 119 | 120 | ### widyr 121 | 122 | Encapsulates the pattern of untidying data into a wide matrix, 123 | performing some processing, then turning it back into a tidy form. This 124 | is useful for several operations such as co-occurrence counts, 125 | correlations, or clustering that are mathematically convenient on wide 126 | matrices. 127 | 128 | [GitHub url](https://github.com/dgrtwo/widyr) 129 | 130 | ----- 131 | 132 | ## Database 133 | 134 | ### dm 135 | 136 | dm bridges the gap in the data pipeline between individual data frames 137 | and relational databases. It’s a grammar of joined tables that provides 138 | a consistent set of verbs for consuming, creating, and deploying 139 | relational data models. For individual researchers, it broadens the 140 | scope of datasets they can work with and how they work with them. For 141 | organizations, it enables teams to quickly and efficiently create and 142 | share large, complex datasets. 143 | 144 | dm objects encapsulate relational data models constructed from local 145 | data frames or lazy tables connected to an RDBMS. dm objects support the 146 | full suite of dplyr data manipulation verbs along with additional 147 | methods for constructing and verifying relational data models, including 148 | key selection, key creation, and rigorous constraint checking. Once a 149 | data model is complete, dm provides methods for deploying it to an 150 | RDBMS. This allows it to scale from datasets that fit in memory to 151 | databases with billions of rows. 152 | 153 | [GitHub url](https://github.com/cynkra/dm) 154 | 155 | ### duckdb 156 | 157 | DuckDB is an in-process SQL OLAP database management system. The 158 | developers say It is : - Simple - Fast - Feature-rich - Free 159 | 160 | [GitHub url](NA) 161 | 162 | ----- 163 | 164 | ## Hospital Coding 165 | 166 | ### ICD 167 | 168 | Calculate comorbidities, medical risk scores, and work very quickly and 169 | precisely with ICD-9 and ICD-10 codes. This package enables a work flow 170 | from raw tables of ICD codes in hospital databases to comorbidities. 171 | ICD-9 and ICD-10 comorbidity mappings from Quan (Deyo and Elixhauser 172 | versions), Elixhauser and AHRQ included. Common ambiguities and code 173 | formats are handled. Comorbidity computation includes Hierarchical 174 | Condition Codes, and an implementation of AHRQ Clinical Classifications. 175 | Risk scores include those of Charlson and van Walraven. US Clinical 176 | Modification, Word Health Organization, Belgian and French ICD-10 codes 177 | are supported, most of which are downloaded on demand. 178 | 179 | [GitHub url](https://github.com/jackwasey/icd) 180 | 181 | ### Rdiagnosislist 182 | 183 | This is an R package for using the SNOMED CT hierarchy and manipulating 184 | lists of SNOMED CT codes. 185 | 186 | It includes functions for loading a SNOMED CT distribution into an R 187 | environment, searching for concepts by regular expression search, 188 | finding attributes of concepts, navigating the hierarchy, and handling 189 | lists of SNOMED CT concepts. 190 | 191 | [GitHub url](https://github.com/anoopshah/Rdiagnosislist) 192 | 193 | ### robson10classifier 194 | 195 | The main function implemented so far is tgcs\_classify(). It takes as an 196 | input a data frame containing a minimum of 6 columns, one for each of 197 | the obstetric variables that are used to classify the Robson Groups. 198 | Each row in the data frame represents a birth. The function returns the 199 | same data frame, with an additional column for Robson\_Classification. 200 | This can be a number from 1 to 10, or in the case that data required for 201 | classification was missing, “Unclassifiable”. 202 | 203 | [GitHub url](https://github.com/ThomUK/robson10classifier) 204 | 205 | ----- 206 | 207 | ## Modelling 208 | 209 | ### performance 210 | 211 | Test if your model is a good model\! 212 | 213 | A crucial aspect when building regression models is to evaluate the 214 | quality of modelfit. It is important to investigate how well models fit 215 | to the data and which fit indices to report. Functions to create 216 | diagnostic plots or to compute fit measures do exist, however, mostly 217 | spread over different packages. There is no unique and consistent 218 | approach to assess the model quality for different kind of models. 219 | 220 | The primary goal of the performance package is to fill this gap and to 221 | provide utilities for computing indices of model quality and goodness of 222 | fit. These include measures like r-squared (R2), root mean squared error 223 | (RMSE) or intraclass correlation coefficient (ICC) , but also functions 224 | to check (mixed) models for overdispersion, zero-inflation, convergence 225 | or singularity. 226 | 227 | [GitHub url](https://easystats.github.io/performance/) 228 | 229 | ----- 230 | 231 | ## Reproducibility 232 | 233 | ### targets 234 | 235 | The targets package is a Make-like pipeline toolkit for Statistics and 236 | data science in R. With targets, you can maintain a reproducible 237 | workflow without repeating yourself. targets learns how your pipeline 238 | fits together, skips costly runtime for tasks that are already up to 239 | date, runs only the necessary computation, supports implicit parallel 240 | computing, abstracts files as R objects, and shows tangible evidence 241 | that the results match the underlying code and data. 242 | 243 | [GitHub url](https://docs.ropensci.org/targets/) 244 | 245 | ### tracdown 246 | 247 | The trackdown package offers a simple solution for collaborative writing 248 | and editing of R Markdown (or Sweave) documents. Using trackdown, the 249 | local .Rmd (or .Rnw) file can be uploaded as a plain-text file to Google 250 | Drive. By taking advantage of the easily readable Markdown (or LaTeX) 251 | syntax and the well-known online interface offered by Google Docs, 252 | collaborators can easily contribute to the writing and editing process. 253 | After integrating all authors’ contributions, the final document can be 254 | downloaded and rendered locally. 255 | 256 | [GitHub url](https://github.com/claudiozandonella/trackdown/) 257 | 258 | ----- 259 | 260 | ## External data resource 261 | 262 | ### a11ytables 263 | 264 | An R package to help you create spreadsheets that adhere to the latest 265 | guidance (June 2021) on releasing statistics in spreadsheets from the 266 | Best Practice and Impact Division (BPID) of the UK’s Government 267 | Statistical Service. 268 | 269 | [GitHub url](https://github.com/co-analysis/a11ytables) 270 | 271 | ### addressMatchR 272 | 273 | Helper package for matching addresses with an integration to Ordnance 274 | Survey API. This R package has been developed by NHS Business Services 275 | Authority Data Science team. 276 | 277 | [GitHub url](https://github.com/nhsbsa-data-analytics/addressMatchR) 278 | 279 | ### Deprivare 280 | 281 | This provides code and data for indices of deprivation, initially 282 | supporting the UK. 283 | 284 | We know socio-economic deprivation has a significant effect on health 285 | outcomes. 286 | 287 | This repository provides a simple microservice, embeddable library and 288 | command-line tools to allow other software to make use of deprivation 289 | indices in the UK 290 | 291 | [GitHub url](https://github.com/wardle/deprivare) 292 | 293 | ### geographr 294 | 295 | geographr is an R package for mapping UK geographies . Package include 296 | geographical geospatial data sets (boundaries and lookups) eg CCG 297 | boundaries 298 | 299 | [GitHub url](https://github.com/britishredcrosssociety/geographr) 300 | 301 | ### LSOA POP 302 | 303 | An R data package with Lower layer Super Output Area (LSOA) population 304 | estimates and Indices of Multiple Deprivation (IMD) for England 305 | 306 | [GitHub url](https://nhs-r-community.github.io/LSOApop/) 307 | 308 | ### medicaldata 309 | 310 | This is a data package with 15 medical datasets for teaching 311 | Reproducible Medical Research with R. The link to the pkgdown reference 312 | website for {medicaldata} is here and in the links at the right. This 313 | package will be useful for anyone teaching R to medical professionals, 314 | including doctors, nurses, trainees, and students. 315 | 316 | [GitHub url](https://github.com/higgi13425/medicaldata/) 317 | 318 | ### MHDS-pipeline 319 | 320 | This is a data processing pipeline for the NHS Mental Health Services 321 | Data Set 322 | 323 | [GitHub url](https://github.com/sg-peytrignet/MHSDS-pipeline) 324 | 325 | ### RCPCH - Digital growth charts server 326 | 327 | An API server and suite of tools which calculates growth centiles and 328 | other growth related data for children. This is the basis of the RCPCH 329 | Digital Growth Charts API. 330 | 331 | Built with FastAPI in Python. 332 | 333 | [GitHub url](https://dev.rcpch.ac.uk/) 334 | 335 | ----- 336 | 337 | ## R Development 338 | 339 | ### dbcooper 340 | 341 | The dbcooper package turns a database connection into a collection of 342 | functions, handling logic for keeping track of connections and letting 343 | you take advantage of autocompletion when exploring a database. 344 | 345 | It’s especially helpful to use when authoring database-specific R 346 | packages, for instance in an internal company package or one wrapping a 347 | public data source. 348 | 349 | [GitHub url](https://github.com/dgrtwo/dbcooper) 350 | 351 | ### devtoolbox 352 | 353 | rstats package for creating a single report on your package’s usage 354 | stats, dependency network, and \#GitHub PR/issues summary\! 355 | 356 | [GitHub url](https://github.com/martinctc/devtoolbox) 357 | 358 | ### difftastic 359 | 360 | Difftastic is an experimental diff tool that compares files based on 361 | their syntax. 362 | 363 | 1) Difftastic understands nesting. It highlights e.g. the matching { 364 | and } 365 | 366 | 2) Difftastic understands which lines should be aligned 367 | 368 | 3) Difftastic understands that line-wrapping isn’t meaningful 369 | 370 | [GitHub url](https://github.com/Wilfred/difftastic) 371 | 372 | ### Material for forwards workshops 373 | 374 | The repo hosts the materials for workshop on R package development. The 375 | links within the repo take you to the presentation slides, which refer 376 | to online materials for the exercises and further reference. All 377 | material in this repo is CC-BY-NC-SA. 378 | 379 | [GitHub 380 | url](https://github.com/forwards/workshops/tree/dc5b9fba5cdfbebc737a0a393b374a18378be122) 381 | 382 | ### riskmetric 383 | 384 | riskmetric is a collection of risk metrics to evaluate the quality of R 385 | packages. 386 | 387 | This package is in experimentation. Final considerations about design 388 | are being considered, but core concepts are considered final. 389 | 390 | [GitHub url](https://github.com/pharmaR/riskmetric) 391 | 392 | ----- 393 | 394 | ## Rstudio Plugin 395 | 396 | ### remedy 397 | 398 | Write quicker in markdown with {remedy}\! Adds a plugin to. RStudio to 399 | enable easier formatting of markdown 400 | 401 | [GitHub url](https://github.com/ThinkR-open/remedy) 402 | 403 | ----- 404 | 405 | ## Rscript or function 406 | 407 | ### Package download tracker 408 | 409 | A fuction that can be used to visualise package download metrics for 410 | packages on CRAN 411 | 412 | [GitHub 413 | url](https://github.com/StatsGary/PackageTracker/blob/main/PackageTracker.R) 414 | 415 | ### RAG Quadrant icons 416 | 417 | Tom wrote some code to make .png quadrant icons to summarise data 418 | quality. 419 | 420 | The icons are made using the {grid} package, and quite easy to change 421 | around if you need something slightly different. Hopefully it might come 422 | in handy to others here. 423 | 424 | [GitHub url](https://github.com/ThomUK/STAR-quadrant-icon-maker) 425 | 426 | ### renv-install-system-deps - GitHub action 427 | 428 | NA 429 | 430 | [GitHub url](https://github.com/tomjemmett/renv-install-system-deps) 431 | 432 | ### setup-r-icons - GitHub actions 433 | 434 | NA 435 | 436 | [GitHub url](https://github.com/tomjemmett/setup-r-icons) 437 | 438 | ### smokingPrevalence 439 | 440 | The goal of smokingPrevalence is to store functions that are used in 441 | analysis for smoking prevalence including ONS public prevalence 442 | information to compare to. 443 | 444 | [GitHub url](https://lextuga007.github.io/smokingPrevalence/index.html) 445 | 446 | ----- 447 | 448 | ## Links 449 | 450 | ### Getting started with unit testing in R 451 | 452 | NA 453 | 454 | [GitHub url](NA) 455 | 456 | ### GitHub CLI 457 | 458 | GitHub CLI brings GitHub to your terminal. Free and open source. 459 | 460 | [GitHub url](https://cli.github.com) 461 | 462 | ### Postcode deprivation finder 463 | 464 | A web page where the Deprivation data for a postcode can be obtained 465 | 466 | [GitHub url](NA) 467 | 468 | ----- 469 | 470 | ## Resources in other languages 471 | 472 | ### lux 473 | 474 | Lux is a Python library that facilitate fast and easy data exploration 475 | by automating the visualization and data analysis process. By simply 476 | printing out a dataframe in a Jupyter notebook, Lux recommends a set of 477 | visualizations highlighting interesting trends and patterns in the 478 | dataset. Visualizations are displayed via an interactive widget that 479 | enables users to quickly browse through large collections of 480 | visualizations and make sense of their data. 481 | 482 | [GitHub url](https://github.com/lux-org/lux) 483 | 484 | ### mermaid \[JAVASCRIPT\] 485 | 486 | Mermaid lets you create diagrams and visualizations using text and code. 487 | 488 | It is a Javascript based diagramming and charting tool that renders 489 | Markdown-inspired text definitions to create and modify diagrams 490 | dynamically. 491 | 492 | If you are familiar with Markdown you should have no problem learning 493 | Mermaid’s Syntax. 494 | 495 | [GitHub url](http://mermaid-js.github.io/mermaid/) 496 | 497 | ### Tidypolars 498 | 499 | tidypolars is a data frame library built on top of the blazingly fast 500 | polars library that gives access to methods and functions familiar to R 501 | tidyverse users. 502 | 503 | [GitHub url](https://github.com/markfairbanks/tidypolars) 504 | -------------------------------------------------------------------------------- /renv/activate.R: -------------------------------------------------------------------------------- 1 | 2 | local({ 3 | 4 | # the requested version of renv 5 | version <- "0.15.4" 6 | 7 | # the project directory 8 | project <- getwd() 9 | 10 | # figure out whether the autoloader is enabled 11 | enabled <- local({ 12 | 13 | # first, check config option 14 | override <- getOption("renv.config.autoloader.enabled") 15 | if (!is.null(override)) 16 | return(override) 17 | 18 | # next, check environment variables 19 | # TODO: prefer using the configuration one in the future 20 | envvars <- c( 21 | "RENV_CONFIG_AUTOLOADER_ENABLED", 22 | "RENV_AUTOLOADER_ENABLED", 23 | "RENV_ACTIVATE_PROJECT" 24 | ) 25 | 26 | for (envvar in envvars) { 27 | envval <- Sys.getenv(envvar, unset = NA) 28 | if (!is.na(envval)) 29 | return(tolower(envval) %in% c("true", "t", "1")) 30 | } 31 | 32 | # enable by default 33 | TRUE 34 | 35 | }) 36 | 37 | if (!enabled) 38 | return(FALSE) 39 | 40 | # avoid recursion 41 | if (identical(getOption("renv.autoloader.running"), TRUE)) { 42 | warning("ignoring recursive attempt to run renv autoloader") 43 | return(invisible(TRUE)) 44 | } 45 | 46 | # signal that we're loading renv during R startup 47 | options(renv.autoloader.running = TRUE) 48 | on.exit(options(renv.autoloader.running = NULL), add = TRUE) 49 | 50 | # signal that we've consented to use renv 51 | options(renv.consent = TRUE) 52 | 53 | # load the 'utils' package eagerly -- this ensures that renv shims, which 54 | # mask 'utils' packages, will come first on the search path 55 | library(utils, lib.loc = .Library) 56 | 57 | # unload renv if it's already been laoded 58 | if ("renv" %in% loadedNamespaces()) 59 | unloadNamespace("renv") 60 | 61 | # load bootstrap tools 62 | `%||%` <- function(x, y) { 63 | if (is.environment(x) || length(x)) x else y 64 | } 65 | 66 | bootstrap <- function(version, library) { 67 | 68 | # attempt to download renv 69 | tarball <- tryCatch(renv_bootstrap_download(version), error = identity) 70 | if (inherits(tarball, "error")) 71 | stop("failed to download renv ", version) 72 | 73 | # now attempt to install 74 | status <- tryCatch(renv_bootstrap_install(version, tarball, library), error = identity) 75 | if (inherits(status, "error")) 76 | stop("failed to install renv ", version) 77 | 78 | } 79 | 80 | renv_bootstrap_tests_running <- function() { 81 | getOption("renv.tests.running", default = FALSE) 82 | } 83 | 84 | renv_bootstrap_repos <- function() { 85 | 86 | # check for repos override 87 | repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA) 88 | if (!is.na(repos)) 89 | return(repos) 90 | 91 | # check for lockfile repositories 92 | repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity) 93 | if (!inherits(repos, "error") && length(repos)) 94 | return(repos) 95 | 96 | # if we're testing, re-use the test repositories 97 | if (renv_bootstrap_tests_running()) 98 | return(getOption("renv.tests.repos")) 99 | 100 | # retrieve current repos 101 | repos <- getOption("repos") 102 | 103 | # ensure @CRAN@ entries are resolved 104 | repos[repos == "@CRAN@"] <- getOption( 105 | "renv.repos.cran", 106 | "https://cloud.r-project.org" 107 | ) 108 | 109 | # add in renv.bootstrap.repos if set 110 | default <- c(FALLBACK = "https://cloud.r-project.org") 111 | extra <- getOption("renv.bootstrap.repos", default = default) 112 | repos <- c(repos, extra) 113 | 114 | # remove duplicates that might've snuck in 115 | dupes <- duplicated(repos) | duplicated(names(repos)) 116 | repos[!dupes] 117 | 118 | } 119 | 120 | renv_bootstrap_repos_lockfile <- function() { 121 | 122 | lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock") 123 | if (!file.exists(lockpath)) 124 | return(NULL) 125 | 126 | lockfile <- tryCatch(renv_json_read(lockpath), error = identity) 127 | if (inherits(lockfile, "error")) { 128 | warning(lockfile) 129 | return(NULL) 130 | } 131 | 132 | repos <- lockfile$R$Repositories 133 | if (length(repos) == 0) 134 | return(NULL) 135 | 136 | keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1)) 137 | vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1)) 138 | names(vals) <- keys 139 | 140 | return(vals) 141 | 142 | } 143 | 144 | renv_bootstrap_download <- function(version) { 145 | 146 | # if the renv version number has 4 components, assume it must 147 | # be retrieved via github 148 | nv <- numeric_version(version) 149 | components <- unclass(nv)[[1]] 150 | 151 | # if this appears to be a development version of 'renv', we'll 152 | # try to restore from github 153 | dev <- length(components) == 4L 154 | 155 | # begin collecting different methods for finding renv 156 | methods <- c( 157 | renv_bootstrap_download_tarball, 158 | if (dev) 159 | renv_bootstrap_download_github 160 | else c( 161 | renv_bootstrap_download_cran_latest, 162 | renv_bootstrap_download_cran_archive 163 | ) 164 | ) 165 | 166 | for (method in methods) { 167 | path <- tryCatch(method(version), error = identity) 168 | if (is.character(path) && file.exists(path)) 169 | return(path) 170 | } 171 | 172 | stop("failed to download renv ", version) 173 | 174 | } 175 | 176 | renv_bootstrap_download_impl <- function(url, destfile) { 177 | 178 | mode <- "wb" 179 | 180 | # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715 181 | fixup <- 182 | Sys.info()[["sysname"]] == "Windows" && 183 | substring(url, 1L, 5L) == "file:" 184 | 185 | if (fixup) 186 | mode <- "w+b" 187 | 188 | utils::download.file( 189 | url = url, 190 | destfile = destfile, 191 | mode = mode, 192 | quiet = TRUE 193 | ) 194 | 195 | } 196 | 197 | renv_bootstrap_download_cran_latest <- function(version) { 198 | 199 | spec <- renv_bootstrap_download_cran_latest_find(version) 200 | 201 | message("* Downloading renv ", version, " ... ", appendLF = FALSE) 202 | 203 | type <- spec$type 204 | repos <- spec$repos 205 | 206 | info <- tryCatch( 207 | utils::download.packages( 208 | pkgs = "renv", 209 | destdir = tempdir(), 210 | repos = repos, 211 | type = type, 212 | quiet = TRUE 213 | ), 214 | condition = identity 215 | ) 216 | 217 | if (inherits(info, "condition")) { 218 | message("FAILED") 219 | return(FALSE) 220 | } 221 | 222 | # report success and return 223 | message("OK (downloaded ", type, ")") 224 | info[1, 2] 225 | 226 | } 227 | 228 | renv_bootstrap_download_cran_latest_find <- function(version) { 229 | 230 | # check whether binaries are supported on this system 231 | binary <- 232 | getOption("renv.bootstrap.binary", default = TRUE) && 233 | !identical(.Platform$pkgType, "source") && 234 | !identical(getOption("pkgType"), "source") && 235 | Sys.info()[["sysname"]] %in% c("Darwin", "Windows") 236 | 237 | types <- c(if (binary) "binary", "source") 238 | 239 | # iterate over types + repositories 240 | for (type in types) { 241 | for (repos in renv_bootstrap_repos()) { 242 | 243 | # retrieve package database 244 | db <- tryCatch( 245 | as.data.frame( 246 | utils::available.packages(type = type, repos = repos), 247 | stringsAsFactors = FALSE 248 | ), 249 | error = identity 250 | ) 251 | 252 | if (inherits(db, "error")) 253 | next 254 | 255 | # check for compatible entry 256 | entry <- db[db$Package %in% "renv" & db$Version %in% version, ] 257 | if (nrow(entry) == 0) 258 | next 259 | 260 | # found it; return spec to caller 261 | spec <- list(entry = entry, type = type, repos = repos) 262 | return(spec) 263 | 264 | } 265 | } 266 | 267 | # if we got here, we failed to find renv 268 | fmt <- "renv %s is not available from your declared package repositories" 269 | stop(sprintf(fmt, version)) 270 | 271 | } 272 | 273 | renv_bootstrap_download_cran_archive <- function(version) { 274 | 275 | name <- sprintf("renv_%s.tar.gz", version) 276 | repos <- renv_bootstrap_repos() 277 | urls <- file.path(repos, "src/contrib/Archive/renv", name) 278 | destfile <- file.path(tempdir(), name) 279 | 280 | message("* Downloading renv ", version, " ... ", appendLF = FALSE) 281 | 282 | for (url in urls) { 283 | 284 | status <- tryCatch( 285 | renv_bootstrap_download_impl(url, destfile), 286 | condition = identity 287 | ) 288 | 289 | if (identical(status, 0L)) { 290 | message("OK") 291 | return(destfile) 292 | } 293 | 294 | } 295 | 296 | message("FAILED") 297 | return(FALSE) 298 | 299 | } 300 | 301 | renv_bootstrap_download_tarball <- function(version) { 302 | 303 | # if the user has provided the path to a tarball via 304 | # an environment variable, then use it 305 | tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA) 306 | if (is.na(tarball)) 307 | return() 308 | 309 | # allow directories 310 | info <- file.info(tarball, extra_cols = FALSE) 311 | if (identical(info$isdir, TRUE)) { 312 | name <- sprintf("renv_%s.tar.gz", version) 313 | tarball <- file.path(tarball, name) 314 | } 315 | 316 | # bail if it doesn't exist 317 | if (!file.exists(tarball)) 318 | return() 319 | 320 | fmt <- "* Bootstrapping with tarball at path '%s'." 321 | msg <- sprintf(fmt, tarball) 322 | message(msg) 323 | 324 | tarball 325 | 326 | } 327 | 328 | renv_bootstrap_download_github <- function(version) { 329 | 330 | enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") 331 | if (!identical(enabled, "TRUE")) 332 | return(FALSE) 333 | 334 | # prepare download options 335 | pat <- Sys.getenv("GITHUB_PAT") 336 | if (nzchar(Sys.which("curl")) && nzchar(pat)) { 337 | fmt <- "--location --fail --header \"Authorization: token %s\"" 338 | extra <- sprintf(fmt, pat) 339 | saved <- options("download.file.method", "download.file.extra") 340 | options(download.file.method = "curl", download.file.extra = extra) 341 | on.exit(do.call(base::options, saved), add = TRUE) 342 | } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { 343 | fmt <- "--header=\"Authorization: token %s\"" 344 | extra <- sprintf(fmt, pat) 345 | saved <- options("download.file.method", "download.file.extra") 346 | options(download.file.method = "wget", download.file.extra = extra) 347 | on.exit(do.call(base::options, saved), add = TRUE) 348 | } 349 | 350 | message("* Downloading renv ", version, " from GitHub ... ", appendLF = FALSE) 351 | 352 | url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version) 353 | name <- sprintf("renv_%s.tar.gz", version) 354 | destfile <- file.path(tempdir(), name) 355 | 356 | status <- tryCatch( 357 | renv_bootstrap_download_impl(url, destfile), 358 | condition = identity 359 | ) 360 | 361 | if (!identical(status, 0L)) { 362 | message("FAILED") 363 | return(FALSE) 364 | } 365 | 366 | message("OK") 367 | return(destfile) 368 | 369 | } 370 | 371 | renv_bootstrap_install <- function(version, tarball, library) { 372 | 373 | # attempt to install it into project library 374 | message("* Installing renv ", version, " ... ", appendLF = FALSE) 375 | dir.create(library, showWarnings = FALSE, recursive = TRUE) 376 | 377 | # invoke using system2 so we can capture and report output 378 | bin <- R.home("bin") 379 | exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" 380 | r <- file.path(bin, exe) 381 | 382 | args <- c( 383 | "--vanilla", "CMD", "INSTALL", "--no-multiarch", 384 | "-l", shQuote(path.expand(library)), 385 | shQuote(path.expand(tarball)) 386 | ) 387 | 388 | output <- system2(r, args, stdout = TRUE, stderr = TRUE) 389 | message("Done!") 390 | 391 | # check for successful install 392 | status <- attr(output, "status") 393 | if (is.numeric(status) && !identical(status, 0L)) { 394 | header <- "Error installing renv:" 395 | lines <- paste(rep.int("=", nchar(header)), collapse = "") 396 | text <- c(header, lines, output) 397 | writeLines(text, con = stderr()) 398 | } 399 | 400 | status 401 | 402 | } 403 | 404 | renv_bootstrap_platform_prefix <- function() { 405 | 406 | # construct version prefix 407 | version <- paste(R.version$major, R.version$minor, sep = ".") 408 | prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-") 409 | 410 | # include SVN revision for development versions of R 411 | # (to avoid sharing platform-specific artefacts with released versions of R) 412 | devel <- 413 | identical(R.version[["status"]], "Under development (unstable)") || 414 | identical(R.version[["nickname"]], "Unsuffered Consequences") 415 | 416 | if (devel) 417 | prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r") 418 | 419 | # build list of path components 420 | components <- c(prefix, R.version$platform) 421 | 422 | # include prefix if provided by user 423 | prefix <- renv_bootstrap_platform_prefix_impl() 424 | if (!is.na(prefix) && nzchar(prefix)) 425 | components <- c(prefix, components) 426 | 427 | # build prefix 428 | paste(components, collapse = "/") 429 | 430 | } 431 | 432 | renv_bootstrap_platform_prefix_impl <- function() { 433 | 434 | # if an explicit prefix has been supplied, use it 435 | prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA) 436 | if (!is.na(prefix)) 437 | return(prefix) 438 | 439 | # if the user has requested an automatic prefix, generate it 440 | auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) 441 | if (auto %in% c("TRUE", "True", "true", "1")) 442 | return(renv_bootstrap_platform_prefix_auto()) 443 | 444 | # empty string on failure 445 | "" 446 | 447 | } 448 | 449 | renv_bootstrap_platform_prefix_auto <- function() { 450 | 451 | prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity) 452 | if (inherits(prefix, "error") || prefix %in% "unknown") { 453 | 454 | msg <- paste( 455 | "failed to infer current operating system", 456 | "please file a bug report at https://github.com/rstudio/renv/issues", 457 | sep = "; " 458 | ) 459 | 460 | warning(msg) 461 | 462 | } 463 | 464 | prefix 465 | 466 | } 467 | 468 | renv_bootstrap_platform_os <- function() { 469 | 470 | sysinfo <- Sys.info() 471 | sysname <- sysinfo[["sysname"]] 472 | 473 | # handle Windows + macOS up front 474 | if (sysname == "Windows") 475 | return("windows") 476 | else if (sysname == "Darwin") 477 | return("macos") 478 | 479 | # check for os-release files 480 | for (file in c("/etc/os-release", "/usr/lib/os-release")) 481 | if (file.exists(file)) 482 | return(renv_bootstrap_platform_os_via_os_release(file, sysinfo)) 483 | 484 | # check for redhat-release files 485 | if (file.exists("/etc/redhat-release")) 486 | return(renv_bootstrap_platform_os_via_redhat_release()) 487 | 488 | "unknown" 489 | 490 | } 491 | 492 | renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) { 493 | 494 | # read /etc/os-release 495 | release <- utils::read.table( 496 | file = file, 497 | sep = "=", 498 | quote = c("\"", "'"), 499 | col.names = c("Key", "Value"), 500 | comment.char = "#", 501 | stringsAsFactors = FALSE 502 | ) 503 | 504 | vars <- as.list(release$Value) 505 | names(vars) <- release$Key 506 | 507 | # get os name 508 | os <- tolower(sysinfo[["sysname"]]) 509 | 510 | # read id 511 | id <- "unknown" 512 | for (field in c("ID", "ID_LIKE")) { 513 | if (field %in% names(vars) && nzchar(vars[[field]])) { 514 | id <- vars[[field]] 515 | break 516 | } 517 | } 518 | 519 | # read version 520 | version <- "unknown" 521 | for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) { 522 | if (field %in% names(vars) && nzchar(vars[[field]])) { 523 | version <- vars[[field]] 524 | break 525 | } 526 | } 527 | 528 | # join together 529 | paste(c(os, id, version), collapse = "-") 530 | 531 | } 532 | 533 | renv_bootstrap_platform_os_via_redhat_release <- function() { 534 | 535 | # read /etc/redhat-release 536 | contents <- readLines("/etc/redhat-release", warn = FALSE) 537 | 538 | # infer id 539 | id <- if (grepl("centos", contents, ignore.case = TRUE)) 540 | "centos" 541 | else if (grepl("redhat", contents, ignore.case = TRUE)) 542 | "redhat" 543 | else 544 | "unknown" 545 | 546 | # try to find a version component (very hacky) 547 | version <- "unknown" 548 | 549 | parts <- strsplit(contents, "[[:space:]]")[[1L]] 550 | for (part in parts) { 551 | 552 | nv <- tryCatch(numeric_version(part), error = identity) 553 | if (inherits(nv, "error")) 554 | next 555 | 556 | version <- nv[1, 1] 557 | break 558 | 559 | } 560 | 561 | paste(c("linux", id, version), collapse = "-") 562 | 563 | } 564 | 565 | renv_bootstrap_library_root_name <- function(project) { 566 | 567 | # use project name as-is if requested 568 | asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE") 569 | if (asis) 570 | return(basename(project)) 571 | 572 | # otherwise, disambiguate based on project's path 573 | id <- substring(renv_bootstrap_hash_text(project), 1L, 8L) 574 | paste(basename(project), id, sep = "-") 575 | 576 | } 577 | 578 | renv_bootstrap_library_root <- function(project) { 579 | 580 | prefix <- renv_bootstrap_profile_prefix() 581 | 582 | path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA) 583 | if (!is.na(path)) 584 | return(paste(c(path, prefix), collapse = "/")) 585 | 586 | path <- renv_bootstrap_library_root_impl(project) 587 | if (!is.null(path)) { 588 | name <- renv_bootstrap_library_root_name(project) 589 | return(paste(c(path, prefix, name), collapse = "/")) 590 | } 591 | 592 | renv_bootstrap_paths_renv("library", project = project) 593 | 594 | } 595 | 596 | renv_bootstrap_library_root_impl <- function(project) { 597 | 598 | root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA) 599 | if (!is.na(root)) 600 | return(root) 601 | 602 | type <- renv_bootstrap_project_type(project) 603 | if (identical(type, "package")) { 604 | userdir <- renv_bootstrap_user_dir() 605 | return(file.path(userdir, "library")) 606 | } 607 | 608 | } 609 | 610 | renv_bootstrap_validate_version <- function(version) { 611 | 612 | loadedversion <- utils::packageDescription("renv", fields = "Version") 613 | if (version == loadedversion) 614 | return(TRUE) 615 | 616 | # assume four-component versions are from GitHub; three-component 617 | # versions are from CRAN 618 | components <- strsplit(loadedversion, "[.-]")[[1]] 619 | remote <- if (length(components) == 4L) 620 | paste("rstudio/renv", loadedversion, sep = "@") 621 | else 622 | paste("renv", loadedversion, sep = "@") 623 | 624 | fmt <- paste( 625 | "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.", 626 | "Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", 627 | "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", 628 | sep = "\n" 629 | ) 630 | 631 | msg <- sprintf(fmt, loadedversion, version, remote) 632 | warning(msg, call. = FALSE) 633 | 634 | FALSE 635 | 636 | } 637 | 638 | renv_bootstrap_hash_text <- function(text) { 639 | 640 | hashfile <- tempfile("renv-hash-") 641 | on.exit(unlink(hashfile), add = TRUE) 642 | 643 | writeLines(text, con = hashfile) 644 | tools::md5sum(hashfile) 645 | 646 | } 647 | 648 | renv_bootstrap_load <- function(project, libpath, version) { 649 | 650 | # try to load renv from the project library 651 | if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) 652 | return(FALSE) 653 | 654 | # warn if the version of renv loaded does not match 655 | renv_bootstrap_validate_version(version) 656 | 657 | # load the project 658 | renv::load(project) 659 | 660 | TRUE 661 | 662 | } 663 | 664 | renv_bootstrap_profile_load <- function(project) { 665 | 666 | # if RENV_PROFILE is already set, just use that 667 | profile <- Sys.getenv("RENV_PROFILE", unset = NA) 668 | if (!is.na(profile) && nzchar(profile)) 669 | return(profile) 670 | 671 | # check for a profile file (nothing to do if it doesn't exist) 672 | path <- renv_bootstrap_paths_renv("profile", profile = FALSE) 673 | if (!file.exists(path)) 674 | return(NULL) 675 | 676 | # read the profile, and set it if it exists 677 | contents <- readLines(path, warn = FALSE) 678 | if (length(contents) == 0L) 679 | return(NULL) 680 | 681 | # set RENV_PROFILE 682 | profile <- contents[[1L]] 683 | if (!profile %in% c("", "default")) 684 | Sys.setenv(RENV_PROFILE = profile) 685 | 686 | profile 687 | 688 | } 689 | 690 | renv_bootstrap_profile_prefix <- function() { 691 | profile <- renv_bootstrap_profile_get() 692 | if (!is.null(profile)) 693 | return(file.path("profiles", profile, "renv")) 694 | } 695 | 696 | renv_bootstrap_profile_get <- function() { 697 | profile <- Sys.getenv("RENV_PROFILE", unset = "") 698 | renv_bootstrap_profile_normalize(profile) 699 | } 700 | 701 | renv_bootstrap_profile_set <- function(profile) { 702 | profile <- renv_bootstrap_profile_normalize(profile) 703 | if (is.null(profile)) 704 | Sys.unsetenv("RENV_PROFILE") 705 | else 706 | Sys.setenv(RENV_PROFILE = profile) 707 | } 708 | 709 | renv_bootstrap_profile_normalize <- function(profile) { 710 | 711 | if (is.null(profile) || profile %in% c("", "default")) 712 | return(NULL) 713 | 714 | profile 715 | 716 | } 717 | 718 | renv_bootstrap_path_absolute <- function(path) { 719 | 720 | substr(path, 1L, 1L) %in% c("~", "/", "\\") || ( 721 | substr(path, 1L, 1L) %in% c(letters, LETTERS) && 722 | substr(path, 2L, 3L) %in% c(":/", ":\\") 723 | ) 724 | 725 | } 726 | 727 | renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) { 728 | renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv") 729 | root <- if (renv_bootstrap_path_absolute(renv)) NULL else project 730 | prefix <- if (profile) renv_bootstrap_profile_prefix() 731 | components <- c(root, renv, prefix, ...) 732 | paste(components, collapse = "/") 733 | } 734 | 735 | renv_bootstrap_project_type <- function(path) { 736 | 737 | descpath <- file.path(path, "DESCRIPTION") 738 | if (!file.exists(descpath)) 739 | return("unknown") 740 | 741 | desc <- tryCatch( 742 | read.dcf(descpath, all = TRUE), 743 | error = identity 744 | ) 745 | 746 | if (inherits(desc, "error")) 747 | return("unknown") 748 | 749 | type <- desc$Type 750 | if (!is.null(type)) 751 | return(tolower(type)) 752 | 753 | package <- desc$Package 754 | if (!is.null(package)) 755 | return("package") 756 | 757 | "unknown" 758 | 759 | } 760 | 761 | renv_bootstrap_user_dir <- function() { 762 | dir <- renv_bootstrap_user_dir_impl() 763 | path.expand(chartr("\\", "/", dir)) 764 | } 765 | 766 | renv_bootstrap_user_dir_impl <- function() { 767 | 768 | # use local override if set 769 | override <- getOption("renv.userdir.override") 770 | if (!is.null(override)) 771 | return(override) 772 | 773 | # use R_user_dir if available 774 | tools <- asNamespace("tools") 775 | if (is.function(tools$R_user_dir)) 776 | return(tools$R_user_dir("renv", "cache")) 777 | 778 | # try using our own backfill for older versions of R 779 | envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME") 780 | for (envvar in envvars) { 781 | root <- Sys.getenv(envvar, unset = NA) 782 | if (!is.na(root)) 783 | return(file.path(root, "R/renv")) 784 | } 785 | 786 | # use platform-specific default fallbacks 787 | if (Sys.info()[["sysname"]] == "Windows") 788 | file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv") 789 | else if (Sys.info()[["sysname"]] == "Darwin") 790 | "~/Library/Caches/org.R-project.R/R/renv" 791 | else 792 | "~/.cache/R/renv" 793 | 794 | } 795 | 796 | 797 | renv_json_read <- function(file = NULL, text = NULL) { 798 | 799 | text <- paste(text %||% read(file), collapse = "\n") 800 | 801 | # find strings in the JSON 802 | pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' 803 | locs <- gregexpr(pattern, text)[[1]] 804 | 805 | # if any are found, replace them with placeholders 806 | replaced <- text 807 | strings <- character() 808 | replacements <- character() 809 | 810 | if (!identical(c(locs), -1L)) { 811 | 812 | # get the string values 813 | starts <- locs 814 | ends <- locs + attr(locs, "match.length") - 1L 815 | strings <- substring(text, starts, ends) 816 | 817 | # only keep those requiring escaping 818 | strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE) 819 | 820 | # compute replacements 821 | replacements <- sprintf('"\032%i\032"', seq_along(strings)) 822 | 823 | # replace the strings 824 | mapply(function(string, replacement) { 825 | replaced <<- sub(string, replacement, replaced, fixed = TRUE) 826 | }, strings, replacements) 827 | 828 | } 829 | 830 | # transform the JSON into something the R parser understands 831 | transformed <- replaced 832 | transformed <- gsub("[[{]", "list(", transformed) 833 | transformed <- gsub("[]}]", ")", transformed) 834 | transformed <- gsub(":", "=", transformed, fixed = TRUE) 835 | text <- paste(transformed, collapse = "\n") 836 | 837 | # parse it 838 | json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]] 839 | 840 | # construct map between source strings, replaced strings 841 | map <- as.character(parse(text = strings)) 842 | names(map) <- as.character(parse(text = replacements)) 843 | 844 | # convert to list 845 | map <- as.list(map) 846 | 847 | # remap strings in object 848 | remapped <- renv_json_remap(json, map) 849 | 850 | # evaluate 851 | eval(remapped, envir = baseenv()) 852 | 853 | } 854 | 855 | renv_json_remap <- function(json, map) { 856 | 857 | # fix names 858 | if (!is.null(names(json))) { 859 | lhs <- match(names(json), names(map), nomatch = 0L) 860 | rhs <- match(names(map), names(json), nomatch = 0L) 861 | names(json)[rhs] <- map[lhs] 862 | } 863 | 864 | # fix values 865 | if (is.character(json)) 866 | return(map[[json]] %||% json) 867 | 868 | # handle true, false, null 869 | if (is.name(json)) { 870 | text <- as.character(json) 871 | if (text == "true") 872 | return(TRUE) 873 | else if (text == "false") 874 | return(FALSE) 875 | else if (text == "null") 876 | return(NULL) 877 | } 878 | 879 | # recurse 880 | if (is.recursive(json)) { 881 | for (i in seq_along(json)) { 882 | json[i] <- list(renv_json_remap(json[[i]], map)) 883 | } 884 | } 885 | 886 | json 887 | 888 | } 889 | 890 | # load the renv profile, if any 891 | renv_bootstrap_profile_load(project) 892 | 893 | # construct path to library root 894 | root <- renv_bootstrap_library_root(project) 895 | 896 | # construct library prefix for platform 897 | prefix <- renv_bootstrap_platform_prefix() 898 | 899 | # construct full libpath 900 | libpath <- file.path(root, prefix) 901 | 902 | # attempt to load 903 | if (renv_bootstrap_load(project, libpath, version)) 904 | return(TRUE) 905 | 906 | # load failed; inform user we're about to bootstrap 907 | prefix <- paste("# Bootstrapping renv", version) 908 | postfix <- paste(rep.int("-", 77L - nchar(prefix)), collapse = "") 909 | header <- paste(prefix, postfix) 910 | message(header) 911 | 912 | # perform bootstrap 913 | bootstrap(version, libpath) 914 | 915 | # exit early if we're just testing bootstrap 916 | if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) 917 | return(TRUE) 918 | 919 | # try again to load 920 | if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { 921 | message("* Successfully installed and loaded renv ", version, ".") 922 | return(renv::load()) 923 | } 924 | 925 | # failed to download or load renv; warn the user 926 | msg <- c( 927 | "Failed to find an renv installation: the project will not be loaded.", 928 | "Use `renv::activate()` to re-initialize the project." 929 | ) 930 | 931 | warning(paste(msg, collapse = "\n"), call. = FALSE) 932 | 933 | }) 934 | -------------------------------------------------------------------------------- /renv.lock: -------------------------------------------------------------------------------- 1 | { 2 | "R": { 3 | "Version": "4.2.0", 4 | "Repositories": [ 5 | { 6 | "Name": "CRAN", 7 | "URL": "https://cran.rstudio.com" 8 | } 9 | ] 10 | }, 11 | "Packages": { 12 | "DBI": { 13 | "Package": "DBI", 14 | "Version": "1.1.2", 15 | "Source": "Repository", 16 | "Repository": "CRAN", 17 | "Hash": "dcd1743af4336156873e3ce3c950b8b9", 18 | "Requirements": [] 19 | }, 20 | "MASS": { 21 | "Package": "MASS", 22 | "Version": "7.3-56", 23 | "Source": "Repository", 24 | "Repository": "CRAN", 25 | "Hash": "af0e1955cb80bb36b7988cc657db261e", 26 | "Requirements": [] 27 | }, 28 | "Matrix": { 29 | "Package": "Matrix", 30 | "Version": "1.4-1", 31 | "Source": "Repository", 32 | "Repository": "CRAN", 33 | "Hash": "699c47c606293bdfbc9fd78a93c9c8fe", 34 | "Requirements": [ 35 | "lattice" 36 | ] 37 | }, 38 | "R6": { 39 | "Package": "R6", 40 | "Version": "2.5.1", 41 | "Source": "Repository", 42 | "Repository": "CRAN", 43 | "Hash": "470851b6d5d0ac559e9d01bb352b4021", 44 | "Requirements": [] 45 | }, 46 | "RColorBrewer": { 47 | "Package": "RColorBrewer", 48 | "Version": "1.1-3", 49 | "Source": "Repository", 50 | "Repository": "CRAN", 51 | "Hash": "45f0398006e83a5b10b72a90663d8d8c", 52 | "Requirements": [] 53 | }, 54 | "airtabler": { 55 | "Package": "airtabler", 56 | "Version": "0.1.6", 57 | "Source": "GitHub", 58 | "RemoteType": "github", 59 | "RemoteHost": "api.github.com", 60 | "RemoteUsername": "bergant", 61 | "RemoteRepo": "airtabler", 62 | "RemoteRef": "master", 63 | "RemoteSha": "c53967962a97396dc738fa14e3aa0537c4bc4dac", 64 | "Hash": "3fd0bfd8d89b20e1937e56fb4d09aae4", 65 | "Requirements": [ 66 | "httr", 67 | "jsonlite" 68 | ] 69 | }, 70 | "askpass": { 71 | "Package": "askpass", 72 | "Version": "1.1", 73 | "Source": "Repository", 74 | "Repository": "CRAN", 75 | "Hash": "e8a22846fff485f0be3770c2da758713", 76 | "Requirements": [ 77 | "sys" 78 | ] 79 | }, 80 | "assertthat": { 81 | "Package": "assertthat", 82 | "Version": "0.2.1", 83 | "Source": "Repository", 84 | "Repository": "CRAN", 85 | "Hash": "50c838a310445e954bc13f26f26a6ecf", 86 | "Requirements": [] 87 | }, 88 | "backports": { 89 | "Package": "backports", 90 | "Version": "1.4.1", 91 | "Source": "Repository", 92 | "Repository": "CRAN", 93 | "Hash": "c39fbec8a30d23e721980b8afb31984c", 94 | "Requirements": [] 95 | }, 96 | "base64enc": { 97 | "Package": "base64enc", 98 | "Version": "0.1-3", 99 | "Source": "Repository", 100 | "Repository": "CRAN", 101 | "Hash": "543776ae6848fde2f48ff3816d0628bc", 102 | "Requirements": [] 103 | }, 104 | "bit": { 105 | "Package": "bit", 106 | "Version": "4.0.4", 107 | "Source": "Repository", 108 | "Repository": "CRAN", 109 | "Hash": "f36715f14d94678eea9933af927bc15d", 110 | "Requirements": [] 111 | }, 112 | "bit64": { 113 | "Package": "bit64", 114 | "Version": "4.0.5", 115 | "Source": "Repository", 116 | "Repository": "CRAN", 117 | "Hash": "9fe98599ca456d6552421db0d6772d8f", 118 | "Requirements": [ 119 | "bit" 120 | ] 121 | }, 122 | "blob": { 123 | "Package": "blob", 124 | "Version": "1.2.3", 125 | "Source": "Repository", 126 | "Repository": "CRAN", 127 | "Hash": "10d231579bc9c06ab1c320618808d4ff", 128 | "Requirements": [ 129 | "rlang", 130 | "vctrs" 131 | ] 132 | }, 133 | "broom": { 134 | "Package": "broom", 135 | "Version": "0.8.0", 136 | "Source": "Repository", 137 | "Repository": "CRAN", 138 | "Hash": "fe13cb670e14da57fd7a466578db8ce5", 139 | "Requirements": [ 140 | "backports", 141 | "dplyr", 142 | "ellipsis", 143 | "generics", 144 | "ggplot2", 145 | "glue", 146 | "purrr", 147 | "rlang", 148 | "stringr", 149 | "tibble", 150 | "tidyr" 151 | ] 152 | }, 153 | "bslib": { 154 | "Package": "bslib", 155 | "Version": "0.3.1", 156 | "Source": "Repository", 157 | "Repository": "CRAN", 158 | "Hash": "56ae7e1987b340186a8a5a157c2ec358", 159 | "Requirements": [ 160 | "htmltools", 161 | "jquerylib", 162 | "jsonlite", 163 | "rlang", 164 | "sass" 165 | ] 166 | }, 167 | "callr": { 168 | "Package": "callr", 169 | "Version": "3.7.0", 170 | "Source": "Repository", 171 | "Repository": "CRAN", 172 | "Hash": "461aa75a11ce2400245190ef5d3995df", 173 | "Requirements": [ 174 | "R6", 175 | "processx" 176 | ] 177 | }, 178 | "cellranger": { 179 | "Package": "cellranger", 180 | "Version": "1.1.0", 181 | "Source": "Repository", 182 | "Repository": "CRAN", 183 | "Hash": "f61dbaec772ccd2e17705c1e872e9e7c", 184 | "Requirements": [ 185 | "rematch", 186 | "tibble" 187 | ] 188 | }, 189 | "cli": { 190 | "Package": "cli", 191 | "Version": "3.3.0", 192 | "Source": "Repository", 193 | "Repository": "CRAN", 194 | "Hash": "23abf173c2b783dcc43379ab9bba00ee", 195 | "Requirements": [ 196 | "glue" 197 | ] 198 | }, 199 | "clipr": { 200 | "Package": "clipr", 201 | "Version": "0.8.0", 202 | "Source": "Repository", 203 | "Repository": "CRAN", 204 | "Hash": "3f038e5ac7f41d4ac41ce658c85e3042", 205 | "Requirements": [] 206 | }, 207 | "colorspace": { 208 | "Package": "colorspace", 209 | "Version": "2.0-3", 210 | "Source": "Repository", 211 | "Repository": "CRAN", 212 | "Hash": "bb4341986bc8b914f0f0acf2e4a3f2f7", 213 | "Requirements": [] 214 | }, 215 | "cpp11": { 216 | "Package": "cpp11", 217 | "Version": "0.4.2", 218 | "Source": "Repository", 219 | "Repository": "CRAN", 220 | "Hash": "fa53ce256cd280f468c080a58ea5ba8c", 221 | "Requirements": [] 222 | }, 223 | "crayon": { 224 | "Package": "crayon", 225 | "Version": "1.5.1", 226 | "Source": "Repository", 227 | "Repository": "CRAN", 228 | "Hash": "8dc45fd8a1ee067a92b85ef274e66d6a", 229 | "Requirements": [] 230 | }, 231 | "curl": { 232 | "Package": "curl", 233 | "Version": "4.3.2", 234 | "Source": "Repository", 235 | "Repository": "CRAN", 236 | "Hash": "022c42d49c28e95d69ca60446dbabf88", 237 | "Requirements": [] 238 | }, 239 | "data.table": { 240 | "Package": "data.table", 241 | "Version": "1.14.2", 242 | "Source": "Repository", 243 | "Repository": "CRAN", 244 | "Hash": "36b67b5adf57b292923f5659f5f0c853", 245 | "Requirements": [] 246 | }, 247 | "dbplyr": { 248 | "Package": "dbplyr", 249 | "Version": "2.1.1", 250 | "Source": "Repository", 251 | "Repository": "CRAN", 252 | "Hash": "1f37fa4ab2f5f7eded42f78b9a887182", 253 | "Requirements": [ 254 | "DBI", 255 | "R6", 256 | "assertthat", 257 | "blob", 258 | "dplyr", 259 | "ellipsis", 260 | "glue", 261 | "lifecycle", 262 | "magrittr", 263 | "purrr", 264 | "rlang", 265 | "tibble", 266 | "tidyselect", 267 | "vctrs", 268 | "withr" 269 | ] 270 | }, 271 | "digest": { 272 | "Package": "digest", 273 | "Version": "0.6.29", 274 | "Source": "Repository", 275 | "Repository": "CRAN", 276 | "Hash": "cf6b206a045a684728c3267ef7596190", 277 | "Requirements": [] 278 | }, 279 | "dplyr": { 280 | "Package": "dplyr", 281 | "Version": "1.0.8", 282 | "Source": "Repository", 283 | "Repository": "CRAN", 284 | "Hash": "ef47665e64228a17609d6df877bf86f2", 285 | "Requirements": [ 286 | "R6", 287 | "generics", 288 | "glue", 289 | "lifecycle", 290 | "magrittr", 291 | "pillar", 292 | "rlang", 293 | "tibble", 294 | "tidyselect", 295 | "vctrs" 296 | ] 297 | }, 298 | "dtplyr": { 299 | "Package": "dtplyr", 300 | "Version": "1.2.1", 301 | "Source": "Repository", 302 | "Repository": "CRAN", 303 | "Hash": "f5d195cd5fcc0a77499d9da698ef2ea3", 304 | "Requirements": [ 305 | "crayon", 306 | "data.table", 307 | "dplyr", 308 | "ellipsis", 309 | "glue", 310 | "lifecycle", 311 | "rlang", 312 | "tibble", 313 | "tidyselect", 314 | "vctrs" 315 | ] 316 | }, 317 | "ellipsis": { 318 | "Package": "ellipsis", 319 | "Version": "0.3.2", 320 | "Source": "Repository", 321 | "Repository": "CRAN", 322 | "Hash": "bb0eec2fe32e88d9e2836c2f73ea2077", 323 | "Requirements": [ 324 | "rlang" 325 | ] 326 | }, 327 | "evaluate": { 328 | "Package": "evaluate", 329 | "Version": "0.15", 330 | "Source": "Repository", 331 | "Repository": "CRAN", 332 | "Hash": "699a7a93d08c962d9f8950b2d7a227f1", 333 | "Requirements": [] 334 | }, 335 | "fansi": { 336 | "Package": "fansi", 337 | "Version": "1.0.3", 338 | "Source": "Repository", 339 | "Repository": "CRAN", 340 | "Hash": "83a8afdbe71839506baa9f90eebad7ec", 341 | "Requirements": [] 342 | }, 343 | "farver": { 344 | "Package": "farver", 345 | "Version": "2.1.0", 346 | "Source": "Repository", 347 | "Repository": "CRAN", 348 | "Hash": "c98eb5133d9cb9e1622b8691487f11bb", 349 | "Requirements": [] 350 | }, 351 | "fastmap": { 352 | "Package": "fastmap", 353 | "Version": "1.1.0", 354 | "Source": "Repository", 355 | "Repository": "CRAN", 356 | "Hash": "77bd60a6157420d4ffa93b27cf6a58b8", 357 | "Requirements": [] 358 | }, 359 | "forcats": { 360 | "Package": "forcats", 361 | "Version": "0.5.1", 362 | "Source": "Repository", 363 | "Repository": "CRAN", 364 | "Hash": "81c3244cab67468aac4c60550832655d", 365 | "Requirements": [ 366 | "ellipsis", 367 | "magrittr", 368 | "rlang", 369 | "tibble" 370 | ] 371 | }, 372 | "fs": { 373 | "Package": "fs", 374 | "Version": "1.5.2", 375 | "Source": "Repository", 376 | "Repository": "CRAN", 377 | "Hash": "7c89603d81793f0d5486d91ab1fc6f1d", 378 | "Requirements": [] 379 | }, 380 | "gargle": { 381 | "Package": "gargle", 382 | "Version": "1.2.0", 383 | "Source": "Repository", 384 | "Repository": "CRAN", 385 | "Hash": "9d234e6a87a6f8181792de6dc4a00e39", 386 | "Requirements": [ 387 | "cli", 388 | "fs", 389 | "glue", 390 | "httr", 391 | "jsonlite", 392 | "rappdirs", 393 | "rlang", 394 | "rstudioapi", 395 | "withr" 396 | ] 397 | }, 398 | "generics": { 399 | "Package": "generics", 400 | "Version": "0.1.2", 401 | "Source": "Repository", 402 | "Repository": "CRAN", 403 | "Hash": "177475892cf4a55865868527654a7741", 404 | "Requirements": [] 405 | }, 406 | "ggplot2": { 407 | "Package": "ggplot2", 408 | "Version": "3.3.5", 409 | "Source": "Repository", 410 | "Repository": "CRAN", 411 | "Hash": "d7566c471c7b17e095dd023b9ef155ad", 412 | "Requirements": [ 413 | "MASS", 414 | "digest", 415 | "glue", 416 | "gtable", 417 | "isoband", 418 | "mgcv", 419 | "rlang", 420 | "scales", 421 | "tibble", 422 | "withr" 423 | ] 424 | }, 425 | "glue": { 426 | "Package": "glue", 427 | "Version": "1.6.2", 428 | "Source": "Repository", 429 | "Repository": "CRAN", 430 | "Hash": "4f2596dfb05dac67b9dc558e5c6fba2e", 431 | "Requirements": [] 432 | }, 433 | "googledrive": { 434 | "Package": "googledrive", 435 | "Version": "2.0.0", 436 | "Source": "Repository", 437 | "Repository": "CRAN", 438 | "Hash": "c3a25adbbfbb03f12e6f88c5fb1f3024", 439 | "Requirements": [ 440 | "cli", 441 | "gargle", 442 | "glue", 443 | "httr", 444 | "jsonlite", 445 | "lifecycle", 446 | "magrittr", 447 | "pillar", 448 | "purrr", 449 | "rlang", 450 | "tibble", 451 | "uuid", 452 | "vctrs", 453 | "withr" 454 | ] 455 | }, 456 | "googlesheets4": { 457 | "Package": "googlesheets4", 458 | "Version": "1.0.0", 459 | "Source": "Repository", 460 | "Repository": "CRAN", 461 | "Hash": "9a6564184dc4a81daea4f1d7ce357c6a", 462 | "Requirements": [ 463 | "cellranger", 464 | "cli", 465 | "curl", 466 | "gargle", 467 | "glue", 468 | "googledrive", 469 | "httr", 470 | "ids", 471 | "magrittr", 472 | "purrr", 473 | "rematch2", 474 | "rlang", 475 | "tibble", 476 | "vctrs" 477 | ] 478 | }, 479 | "gtable": { 480 | "Package": "gtable", 481 | "Version": "0.3.0", 482 | "Source": "Repository", 483 | "Repository": "CRAN", 484 | "Hash": "ac5c6baf7822ce8732b343f14c072c4d", 485 | "Requirements": [] 486 | }, 487 | "haven": { 488 | "Package": "haven", 489 | "Version": "2.5.0", 490 | "Source": "Repository", 491 | "Repository": "CRAN", 492 | "Hash": "e3058e4ac77f4fa686f68a1838d5b715", 493 | "Requirements": [ 494 | "cli", 495 | "cpp11", 496 | "forcats", 497 | "hms", 498 | "lifecycle", 499 | "readr", 500 | "rlang", 501 | "tibble", 502 | "tidyselect", 503 | "vctrs" 504 | ] 505 | }, 506 | "highr": { 507 | "Package": "highr", 508 | "Version": "0.9", 509 | "Source": "Repository", 510 | "Repository": "CRAN", 511 | "Hash": "8eb36c8125038e648e5d111c0d7b2ed4", 512 | "Requirements": [ 513 | "xfun" 514 | ] 515 | }, 516 | "hms": { 517 | "Package": "hms", 518 | "Version": "1.1.1", 519 | "Source": "Repository", 520 | "Repository": "CRAN", 521 | "Hash": "5b8a2dd0fdbe2ab4f6081e6c7be6dfca", 522 | "Requirements": [ 523 | "ellipsis", 524 | "lifecycle", 525 | "pkgconfig", 526 | "rlang", 527 | "vctrs" 528 | ] 529 | }, 530 | "htmltools": { 531 | "Package": "htmltools", 532 | "Version": "0.5.2", 533 | "Source": "Repository", 534 | "Repository": "CRAN", 535 | "Hash": "526c484233f42522278ab06fb185cb26", 536 | "Requirements": [ 537 | "base64enc", 538 | "digest", 539 | "fastmap", 540 | "rlang" 541 | ] 542 | }, 543 | "httr": { 544 | "Package": "httr", 545 | "Version": "1.4.2", 546 | "Source": "Repository", 547 | "Repository": "CRAN", 548 | "Hash": "a525aba14184fec243f9eaec62fbed43", 549 | "Requirements": [ 550 | "R6", 551 | "curl", 552 | "jsonlite", 553 | "mime", 554 | "openssl" 555 | ] 556 | }, 557 | "ids": { 558 | "Package": "ids", 559 | "Version": "1.0.1", 560 | "Source": "Repository", 561 | "Repository": "CRAN", 562 | "Hash": "99df65cfef20e525ed38c3d2577f7190", 563 | "Requirements": [ 564 | "openssl", 565 | "uuid" 566 | ] 567 | }, 568 | "isoband": { 569 | "Package": "isoband", 570 | "Version": "0.2.5", 571 | "Source": "Repository", 572 | "Repository": "CRAN", 573 | "Hash": "7ab57a6de7f48a8dc84910d1eca42883", 574 | "Requirements": [] 575 | }, 576 | "janitor": { 577 | "Package": "janitor", 578 | "Version": "2.1.0", 579 | "Source": "Repository", 580 | "Repository": "CRAN", 581 | "Hash": "6de84a8c67fb247e721166049c84695f", 582 | "Requirements": [ 583 | "dplyr", 584 | "lifecycle", 585 | "lubridate", 586 | "magrittr", 587 | "purrr", 588 | "rlang", 589 | "snakecase", 590 | "stringi", 591 | "stringr", 592 | "tidyr", 593 | "tidyselect" 594 | ] 595 | }, 596 | "jquerylib": { 597 | "Package": "jquerylib", 598 | "Version": "0.1.4", 599 | "Source": "Repository", 600 | "Repository": "CRAN", 601 | "Hash": "5aab57a3bd297eee1c1d862735972182", 602 | "Requirements": [ 603 | "htmltools" 604 | ] 605 | }, 606 | "jsonlite": { 607 | "Package": "jsonlite", 608 | "Version": "1.8.0", 609 | "Source": "Repository", 610 | "Repository": "CRAN", 611 | "Hash": "d07e729b27b372429d42d24d503613a0", 612 | "Requirements": [] 613 | }, 614 | "knitr": { 615 | "Package": "knitr", 616 | "Version": "1.39", 617 | "Source": "Repository", 618 | "Repository": "CRAN", 619 | "Hash": "029ab7c4badd3cf8af69016b2ba27493", 620 | "Requirements": [ 621 | "evaluate", 622 | "highr", 623 | "stringr", 624 | "xfun", 625 | "yaml" 626 | ] 627 | }, 628 | "labeling": { 629 | "Package": "labeling", 630 | "Version": "0.4.2", 631 | "Source": "Repository", 632 | "Repository": "CRAN", 633 | "Hash": "3d5108641f47470611a32d0bdf357a72", 634 | "Requirements": [] 635 | }, 636 | "lattice": { 637 | "Package": "lattice", 638 | "Version": "0.20-45", 639 | "Source": "Repository", 640 | "Repository": "CRAN", 641 | "Hash": "b64cdbb2b340437c4ee047a1f4c4377b", 642 | "Requirements": [] 643 | }, 644 | "lifecycle": { 645 | "Package": "lifecycle", 646 | "Version": "1.0.1", 647 | "Source": "Repository", 648 | "Repository": "CRAN", 649 | "Hash": "a6b6d352e3ed897373ab19d8395c98d0", 650 | "Requirements": [ 651 | "glue", 652 | "rlang" 653 | ] 654 | }, 655 | "lubridate": { 656 | "Package": "lubridate", 657 | "Version": "1.8.0", 658 | "Source": "Repository", 659 | "Repository": "CRAN", 660 | "Hash": "2ff5eedb6ee38fb1b81205c73be1be5a", 661 | "Requirements": [ 662 | "cpp11", 663 | "generics" 664 | ] 665 | }, 666 | "magrittr": { 667 | "Package": "magrittr", 668 | "Version": "2.0.3", 669 | "Source": "Repository", 670 | "Repository": "CRAN", 671 | "Hash": "7ce2733a9826b3aeb1775d56fd305472", 672 | "Requirements": [] 673 | }, 674 | "mgcv": { 675 | "Package": "mgcv", 676 | "Version": "1.8-40", 677 | "Source": "Repository", 678 | "Repository": "CRAN", 679 | "Hash": "c6b2fdb18cf68ab613bd564363e1ba0d", 680 | "Requirements": [ 681 | "Matrix", 682 | "nlme" 683 | ] 684 | }, 685 | "mime": { 686 | "Package": "mime", 687 | "Version": "0.12", 688 | "Source": "Repository", 689 | "Repository": "CRAN", 690 | "Hash": "18e9c28c1d3ca1560ce30658b22ce104", 691 | "Requirements": [] 692 | }, 693 | "modelr": { 694 | "Package": "modelr", 695 | "Version": "0.1.8", 696 | "Source": "Repository", 697 | "Repository": "CRAN", 698 | "Hash": "9fd59716311ee82cba83dc2826fc5577", 699 | "Requirements": [ 700 | "broom", 701 | "magrittr", 702 | "purrr", 703 | "rlang", 704 | "tibble", 705 | "tidyr", 706 | "tidyselect", 707 | "vctrs" 708 | ] 709 | }, 710 | "munsell": { 711 | "Package": "munsell", 712 | "Version": "0.5.0", 713 | "Source": "Repository", 714 | "Repository": "CRAN", 715 | "Hash": "6dfe8bf774944bd5595785e3229d8771", 716 | "Requirements": [ 717 | "colorspace" 718 | ] 719 | }, 720 | "nlme": { 721 | "Package": "nlme", 722 | "Version": "3.1-157", 723 | "Source": "Repository", 724 | "Repository": "CRAN", 725 | "Hash": "dbca60742be0c9eddc5205e5c7ca1f44", 726 | "Requirements": [ 727 | "lattice" 728 | ] 729 | }, 730 | "openssl": { 731 | "Package": "openssl", 732 | "Version": "2.0.0", 733 | "Source": "Repository", 734 | "Repository": "CRAN", 735 | "Hash": "cf4329aac12c2c44089974559c18e446", 736 | "Requirements": [ 737 | "askpass" 738 | ] 739 | }, 740 | "pillar": { 741 | "Package": "pillar", 742 | "Version": "1.7.0", 743 | "Source": "Repository", 744 | "Repository": "CRAN", 745 | "Hash": "51dfc97e1b7069e9f7e6f83f3589c22e", 746 | "Requirements": [ 747 | "cli", 748 | "crayon", 749 | "ellipsis", 750 | "fansi", 751 | "glue", 752 | "lifecycle", 753 | "rlang", 754 | "utf8", 755 | "vctrs" 756 | ] 757 | }, 758 | "pkgconfig": { 759 | "Package": "pkgconfig", 760 | "Version": "2.0.3", 761 | "Source": "Repository", 762 | "Repository": "CRAN", 763 | "Hash": "01f28d4278f15c76cddbea05899c5d6f", 764 | "Requirements": [] 765 | }, 766 | "prettyunits": { 767 | "Package": "prettyunits", 768 | "Version": "1.1.1", 769 | "Source": "Repository", 770 | "Repository": "CRAN", 771 | "Hash": "95ef9167b75dde9d2ccc3c7528393e7e", 772 | "Requirements": [] 773 | }, 774 | "processx": { 775 | "Package": "processx", 776 | "Version": "3.5.3", 777 | "Source": "Repository", 778 | "Repository": "CRAN", 779 | "Hash": "8bbae1a548d0d3fdf6647bdd9d35bf6d", 780 | "Requirements": [ 781 | "R6", 782 | "ps" 783 | ] 784 | }, 785 | "progress": { 786 | "Package": "progress", 787 | "Version": "1.2.2", 788 | "Source": "Repository", 789 | "Repository": "CRAN", 790 | "Hash": "14dc9f7a3c91ebb14ec5bb9208a07061", 791 | "Requirements": [ 792 | "R6", 793 | "crayon", 794 | "hms", 795 | "prettyunits" 796 | ] 797 | }, 798 | "ps": { 799 | "Package": "ps", 800 | "Version": "1.7.0", 801 | "Source": "Repository", 802 | "Repository": "CRAN", 803 | "Hash": "eef74b13f32cae6bb0d495e53317c44c", 804 | "Requirements": [] 805 | }, 806 | "purrr": { 807 | "Package": "purrr", 808 | "Version": "0.3.4", 809 | "Source": "Repository", 810 | "Repository": "CRAN", 811 | "Hash": "97def703420c8ab10d8f0e6c72101e02", 812 | "Requirements": [ 813 | "magrittr", 814 | "rlang" 815 | ] 816 | }, 817 | "rappdirs": { 818 | "Package": "rappdirs", 819 | "Version": "0.3.3", 820 | "Source": "Repository", 821 | "Repository": "CRAN", 822 | "Hash": "5e3c5dc0b071b21fa128676560dbe94d", 823 | "Requirements": [] 824 | }, 825 | "readr": { 826 | "Package": "readr", 827 | "Version": "2.1.2", 828 | "Source": "Repository", 829 | "Repository": "CRAN", 830 | "Hash": "9c59de1357dc209868b5feb5c9f0fe2f", 831 | "Requirements": [ 832 | "R6", 833 | "cli", 834 | "clipr", 835 | "cpp11", 836 | "crayon", 837 | "hms", 838 | "lifecycle", 839 | "rlang", 840 | "tibble", 841 | "tzdb", 842 | "vroom" 843 | ] 844 | }, 845 | "readxl": { 846 | "Package": "readxl", 847 | "Version": "1.4.0", 848 | "Source": "Repository", 849 | "Repository": "CRAN", 850 | "Hash": "170c35f745563bb307e963bde0197e4f", 851 | "Requirements": [ 852 | "cellranger", 853 | "cpp11", 854 | "progress", 855 | "tibble" 856 | ] 857 | }, 858 | "rematch": { 859 | "Package": "rematch", 860 | "Version": "1.0.1", 861 | "Source": "Repository", 862 | "Repository": "CRAN", 863 | "Hash": "c66b930d20bb6d858cd18e1cebcfae5c", 864 | "Requirements": [] 865 | }, 866 | "rematch2": { 867 | "Package": "rematch2", 868 | "Version": "2.1.2", 869 | "Source": "Repository", 870 | "Repository": "CRAN", 871 | "Hash": "76c9e04c712a05848ae7a23d2f170a40", 872 | "Requirements": [ 873 | "tibble" 874 | ] 875 | }, 876 | "renv": { 877 | "Package": "renv", 878 | "Version": "0.15.4", 879 | "Source": "Repository", 880 | "Repository": "CRAN", 881 | "Hash": "c1078316e1d4f70275fc1ea60c0bc431", 882 | "Requirements": [] 883 | }, 884 | "reprex": { 885 | "Package": "reprex", 886 | "Version": "2.0.1", 887 | "Source": "Repository", 888 | "Repository": "CRAN", 889 | "Hash": "911d101becedc0fde495bd910984bdc8", 890 | "Requirements": [ 891 | "callr", 892 | "cli", 893 | "clipr", 894 | "fs", 895 | "glue", 896 | "knitr", 897 | "rlang", 898 | "rmarkdown", 899 | "rstudioapi", 900 | "withr" 901 | ] 902 | }, 903 | "rlang": { 904 | "Package": "rlang", 905 | "Version": "1.0.2", 906 | "Source": "Repository", 907 | "Repository": "CRAN", 908 | "Hash": "04884d9a75d778aca22c7154b8333ec9", 909 | "Requirements": [] 910 | }, 911 | "rmarkdown": { 912 | "Package": "rmarkdown", 913 | "Version": "2.14", 914 | "Source": "Repository", 915 | "Repository": "CRAN", 916 | "Hash": "31b60a882fabfabf6785b8599ffeb8ba", 917 | "Requirements": [ 918 | "bslib", 919 | "evaluate", 920 | "htmltools", 921 | "jquerylib", 922 | "jsonlite", 923 | "knitr", 924 | "stringr", 925 | "tinytex", 926 | "xfun", 927 | "yaml" 928 | ] 929 | }, 930 | "rstudioapi": { 931 | "Package": "rstudioapi", 932 | "Version": "0.13", 933 | "Source": "Repository", 934 | "Repository": "CRAN", 935 | "Hash": "06c85365a03fdaf699966cc1d3cf53ea", 936 | "Requirements": [] 937 | }, 938 | "rvest": { 939 | "Package": "rvest", 940 | "Version": "1.0.2", 941 | "Source": "Repository", 942 | "Repository": "CRAN", 943 | "Hash": "bb099886deffecd6f9b298b7d4492943", 944 | "Requirements": [ 945 | "httr", 946 | "lifecycle", 947 | "magrittr", 948 | "rlang", 949 | "selectr", 950 | "tibble", 951 | "xml2" 952 | ] 953 | }, 954 | "sass": { 955 | "Package": "sass", 956 | "Version": "0.4.1", 957 | "Source": "Repository", 958 | "Repository": "CRAN", 959 | "Hash": "f37c0028d720bab3c513fd65d28c7234", 960 | "Requirements": [ 961 | "R6", 962 | "fs", 963 | "htmltools", 964 | "rappdirs", 965 | "rlang" 966 | ] 967 | }, 968 | "scales": { 969 | "Package": "scales", 970 | "Version": "1.2.0", 971 | "Source": "Repository", 972 | "Repository": "CRAN", 973 | "Hash": "6e8750cdd13477aa440d453da93d5cac", 974 | "Requirements": [ 975 | "R6", 976 | "RColorBrewer", 977 | "farver", 978 | "labeling", 979 | "lifecycle", 980 | "munsell", 981 | "rlang", 982 | "viridisLite" 983 | ] 984 | }, 985 | "selectr": { 986 | "Package": "selectr", 987 | "Version": "0.4-2", 988 | "Source": "Repository", 989 | "Repository": "CRAN", 990 | "Hash": "3838071b66e0c566d55cc26bd6e27bf4", 991 | "Requirements": [ 992 | "R6", 993 | "stringr" 994 | ] 995 | }, 996 | "snakecase": { 997 | "Package": "snakecase", 998 | "Version": "0.11.0", 999 | "Source": "Repository", 1000 | "Repository": "CRAN", 1001 | "Hash": "4079070fc210c7901c0832a3aeab894f", 1002 | "Requirements": [ 1003 | "stringi", 1004 | "stringr" 1005 | ] 1006 | }, 1007 | "stringi": { 1008 | "Package": "stringi", 1009 | "Version": "1.7.6", 1010 | "Source": "Repository", 1011 | "Repository": "CRAN", 1012 | "Hash": "bba431031d30789535745a9627ac9271", 1013 | "Requirements": [] 1014 | }, 1015 | "stringr": { 1016 | "Package": "stringr", 1017 | "Version": "1.4.0", 1018 | "Source": "Repository", 1019 | "Repository": "CRAN", 1020 | "Hash": "0759e6b6c0957edb1311028a49a35e76", 1021 | "Requirements": [ 1022 | "glue", 1023 | "magrittr", 1024 | "stringi" 1025 | ] 1026 | }, 1027 | "sys": { 1028 | "Package": "sys", 1029 | "Version": "3.4", 1030 | "Source": "Repository", 1031 | "Repository": "CRAN", 1032 | "Hash": "b227d13e29222b4574486cfcbde077fa", 1033 | "Requirements": [] 1034 | }, 1035 | "tibble": { 1036 | "Package": "tibble", 1037 | "Version": "3.1.6", 1038 | "Source": "Repository", 1039 | "Repository": "CRAN", 1040 | "Hash": "8a8f02d1934dfd6431c671361510dd0b", 1041 | "Requirements": [ 1042 | "ellipsis", 1043 | "fansi", 1044 | "lifecycle", 1045 | "magrittr", 1046 | "pillar", 1047 | "pkgconfig", 1048 | "rlang", 1049 | "vctrs" 1050 | ] 1051 | }, 1052 | "tidyr": { 1053 | "Package": "tidyr", 1054 | "Version": "1.2.0", 1055 | "Source": "Repository", 1056 | "Repository": "CRAN", 1057 | "Hash": "d8b95b7fee945d7da6888cf7eb71a49c", 1058 | "Requirements": [ 1059 | "cpp11", 1060 | "dplyr", 1061 | "ellipsis", 1062 | "glue", 1063 | "lifecycle", 1064 | "magrittr", 1065 | "purrr", 1066 | "rlang", 1067 | "tibble", 1068 | "tidyselect", 1069 | "vctrs" 1070 | ] 1071 | }, 1072 | "tidyselect": { 1073 | "Package": "tidyselect", 1074 | "Version": "1.1.2", 1075 | "Source": "Repository", 1076 | "Repository": "CRAN", 1077 | "Hash": "17f6da8cfd7002760a859915ce7eef8f", 1078 | "Requirements": [ 1079 | "ellipsis", 1080 | "glue", 1081 | "purrr", 1082 | "rlang", 1083 | "vctrs" 1084 | ] 1085 | }, 1086 | "tidyverse": { 1087 | "Package": "tidyverse", 1088 | "Version": "1.3.1", 1089 | "Source": "Repository", 1090 | "Repository": "CRAN", 1091 | "Hash": "fc4c72b6ae9bb283416bd59a3303bbab", 1092 | "Requirements": [ 1093 | "broom", 1094 | "cli", 1095 | "crayon", 1096 | "dbplyr", 1097 | "dplyr", 1098 | "dtplyr", 1099 | "forcats", 1100 | "ggplot2", 1101 | "googledrive", 1102 | "googlesheets4", 1103 | "haven", 1104 | "hms", 1105 | "httr", 1106 | "jsonlite", 1107 | "lubridate", 1108 | "magrittr", 1109 | "modelr", 1110 | "pillar", 1111 | "purrr", 1112 | "readr", 1113 | "readxl", 1114 | "reprex", 1115 | "rlang", 1116 | "rstudioapi", 1117 | "rvest", 1118 | "stringr", 1119 | "tibble", 1120 | "tidyr", 1121 | "xml2" 1122 | ] 1123 | }, 1124 | "tinytex": { 1125 | "Package": "tinytex", 1126 | "Version": "0.38", 1127 | "Source": "Repository", 1128 | "Repository": "CRAN", 1129 | "Hash": "759d047596ac173433985deddf313450", 1130 | "Requirements": [ 1131 | "xfun" 1132 | ] 1133 | }, 1134 | "tzdb": { 1135 | "Package": "tzdb", 1136 | "Version": "0.3.0", 1137 | "Source": "Repository", 1138 | "Repository": "CRAN", 1139 | "Hash": "b2e1cbce7c903eaf23ec05c58e59fb5e", 1140 | "Requirements": [ 1141 | "cpp11" 1142 | ] 1143 | }, 1144 | "utf8": { 1145 | "Package": "utf8", 1146 | "Version": "1.2.2", 1147 | "Source": "Repository", 1148 | "Repository": "CRAN", 1149 | "Hash": "c9c462b759a5cc844ae25b5942654d13", 1150 | "Requirements": [] 1151 | }, 1152 | "uuid": { 1153 | "Package": "uuid", 1154 | "Version": "1.1-0", 1155 | "Source": "Repository", 1156 | "Repository": "CRAN", 1157 | "Hash": "f1cb46c157d080b729159d407be83496", 1158 | "Requirements": [] 1159 | }, 1160 | "vctrs": { 1161 | "Package": "vctrs", 1162 | "Version": "0.4.1", 1163 | "Source": "Repository", 1164 | "Repository": "CRAN", 1165 | "Hash": "8b54f22e2a58c4f275479c92ce041a57", 1166 | "Requirements": [ 1167 | "cli", 1168 | "glue", 1169 | "rlang" 1170 | ] 1171 | }, 1172 | "viridisLite": { 1173 | "Package": "viridisLite", 1174 | "Version": "0.4.0", 1175 | "Source": "Repository", 1176 | "Repository": "CRAN", 1177 | "Hash": "55e157e2aa88161bdb0754218470d204", 1178 | "Requirements": [] 1179 | }, 1180 | "vroom": { 1181 | "Package": "vroom", 1182 | "Version": "1.5.7", 1183 | "Source": "Repository", 1184 | "Repository": "CRAN", 1185 | "Hash": "976507b5a105bc3bdf6a5a5f29e0684f", 1186 | "Requirements": [ 1187 | "bit64", 1188 | "cli", 1189 | "cpp11", 1190 | "crayon", 1191 | "glue", 1192 | "hms", 1193 | "lifecycle", 1194 | "progress", 1195 | "rlang", 1196 | "tibble", 1197 | "tidyselect", 1198 | "tzdb", 1199 | "vctrs", 1200 | "withr" 1201 | ] 1202 | }, 1203 | "withr": { 1204 | "Package": "withr", 1205 | "Version": "2.5.0", 1206 | "Source": "Repository", 1207 | "Repository": "CRAN", 1208 | "Hash": "c0e49a9760983e81e55cdd9be92e7182", 1209 | "Requirements": [] 1210 | }, 1211 | "xfun": { 1212 | "Package": "xfun", 1213 | "Version": "0.30", 1214 | "Source": "Repository", 1215 | "Repository": "CRAN", 1216 | "Hash": "e83f48136b041845e50a6658feffb197", 1217 | "Requirements": [] 1218 | }, 1219 | "xml2": { 1220 | "Package": "xml2", 1221 | "Version": "1.3.3", 1222 | "Source": "Repository", 1223 | "Repository": "CRAN", 1224 | "Hash": "40682ed6a969ea5abfd351eb67833adc", 1225 | "Requirements": [] 1226 | }, 1227 | "yaml": { 1228 | "Package": "yaml", 1229 | "Version": "2.3.5", 1230 | "Source": "Repository", 1231 | "Repository": "CRAN", 1232 | "Hash": "458bb38374d73bf83b1bb85e353da200", 1233 | "Requirements": [] 1234 | } 1235 | } 1236 | } 1237 | --------------------------------------------------------------------------------