From 2a4061fba9ed3a62abadafcbda3faa8d3c83f43c Mon Sep 17 00:00:00 2001 From: Lorenzo Copelli Date: Wed, 1 Apr 2026 18:59:14 +0200 Subject: [PATCH 1/3] Project import. (#1) * First commit (project import). * Added GitHub workflows. --- .Rbuildignore | 21 + .Rprofile | 1 + .github/workflows/codecov.yml | 30 + .github/workflows/pkgdown.yml | 41 + .gitignore | 5 + DESCRIPTION | 47 + EFSATools.Rproj | 19 + LICENSE | 287 +++ NAMESPACE | 33 + R/EFSATools-package.R | 6 + R/SCD2.R | 66 + R/SSCD2.R | 36 + R/activate.R | 31 + R/deactivate.R | 30 + R/dropEmpty.R | 38 + R/enrich.R | 56 + R/removeReplicatedColumns.R | 78 + README.md | 47 +- _pkgdown.yml | 8 + man/EFSATools-package.Rd | 30 + man/SCD2.Rd | 43 + man/SSCD2.Rd | 31 + man/dropEmpty.Rd | 31 + man/enrich.Rd | 44 + man/figures/logo.png | Bin 0 -> 79480 bytes man/removeReplicatedColumns.Rd | 43 + pkgdown/favicon/apple-touch-icon.png | Bin 0 -> 10459 bytes pkgdown/favicon/favicon-96x96.png | Bin 0 -> 4703 bytes pkgdown/favicon/favicon.ico | Bin 0 -> 15086 bytes pkgdown/favicon/favicon.svg | 1 + pkgdown/favicon/site.webmanifest | 21 + pkgdown/favicon/web-app-manifest-192x192.png | Bin 0 -> 11220 bytes pkgdown/favicon/web-app-manifest-512x512.png | Bin 0 -> 41359 bytes renv.lock | 1857 +++++++++++++++++ renv/.gitignore | 7 + renv/activate.R | 1180 +++++++++++ renv/settings.json | 19 + tests/testthat.R | 12 + tests/testthat/test-SCD2.R | 105 + tests/testthat/test-SSCD2.R | 50 + tests/testthat/test-activate.R | 34 + tests/testthat/test-deactivate.R | 32 + tests/testthat/test-dropEmpty.R | 42 + tests/testthat/test-enrich.R | 67 + tests/testthat/test-removeReplicatedColumns.R | 45 + vignettes/.gitignore | 2 + vignettes/EFSATools.Rmd | 134 ++ 47 files changed, 4708 insertions(+), 2 deletions(-) create mode 100644 .Rbuildignore create mode 100644 .Rprofile create mode 100644 .github/workflows/codecov.yml create mode 100644 .github/workflows/pkgdown.yml create mode 100644 .gitignore create mode 100644 DESCRIPTION create mode 100644 EFSATools.Rproj create mode 100644 LICENSE create mode 100644 NAMESPACE create mode 100644 R/EFSATools-package.R create mode 100644 R/SCD2.R create mode 100644 R/SSCD2.R create mode 100644 R/activate.R create mode 100644 R/deactivate.R create mode 100644 R/dropEmpty.R create mode 100644 R/enrich.R create mode 100644 R/removeReplicatedColumns.R create mode 100644 _pkgdown.yml create mode 100644 man/EFSATools-package.Rd create mode 100644 man/SCD2.Rd create mode 100644 man/SSCD2.Rd create mode 100644 man/dropEmpty.Rd create mode 100644 man/enrich.Rd create mode 100644 man/figures/logo.png create mode 100644 man/removeReplicatedColumns.Rd create mode 100644 pkgdown/favicon/apple-touch-icon.png create mode 100644 pkgdown/favicon/favicon-96x96.png create mode 100644 pkgdown/favicon/favicon.ico create mode 100644 pkgdown/favicon/favicon.svg create mode 100644 pkgdown/favicon/site.webmanifest create mode 100644 pkgdown/favicon/web-app-manifest-192x192.png create mode 100644 pkgdown/favicon/web-app-manifest-512x512.png create mode 100644 renv.lock create mode 100644 renv/.gitignore create mode 100644 renv/activate.R create mode 100644 renv/settings.json create mode 100644 tests/testthat.R create mode 100644 tests/testthat/test-SCD2.R create mode 100644 tests/testthat/test-SSCD2.R create mode 100644 tests/testthat/test-activate.R create mode 100644 tests/testthat/test-deactivate.R create mode 100644 tests/testthat/test-dropEmpty.R create mode 100644 tests/testthat/test-enrich.R create mode 100644 tests/testthat/test-removeReplicatedColumns.R create mode 100644 vignettes/.gitignore create mode 100644 vignettes/EFSATools.Rmd diff --git a/.Rbuildignore b/.Rbuildignore new file mode 100644 index 0000000..c50f4b3 --- /dev/null +++ b/.Rbuildignore @@ -0,0 +1,21 @@ +^renv$ +^renv\.lock$ +^.*\.Rproj$ +^\.Rproj\.user$ +^doc$ +^Meta$ +^_pkgdown\.yml$ +^docs$ +^pkgdown$ +^\.travis\.yml$ +^travis-tool\.sh\.cmd$ +^README\.Rmd$ +^README\.md$ +^codecov\.yml$ +^cran-comments\.md$ +^\.github$ +^\.github\/$ +^.github$ +.github +^CRAN-RELEASE$ +^LICENSE\.md$ diff --git a/.Rprofile b/.Rprofile new file mode 100644 index 0000000..81b960f --- /dev/null +++ b/.Rprofile @@ -0,0 +1 @@ +source("renv/activate.R") diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml new file mode 100644 index 0000000..6674536 --- /dev/null +++ b/.github/workflows/codecov.yml @@ -0,0 +1,30 @@ +name: Run tests and upload coverage report to Codecov + +on: + push: + branches: [dev, main] + +jobs: + coverage: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up R + uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - name: Install R dependencies + uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::covr, any::devtools, local::. + needs: coverage + + - name: Run tests and upload coverage to Codecov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + run: | + Rscript -e "covr::codecov(token = Sys.getenv('CODECOV_TOKEN'))" diff --git a/.github/workflows/pkgdown.yml b/.github/workflows/pkgdown.yml new file mode 100644 index 0000000..7e0ce6c --- /dev/null +++ b/.github/workflows/pkgdown.yml @@ -0,0 +1,41 @@ +name: Build and deploy pkgdown site to GitHub Pages + +on: + push: + branches: [main] + +jobs: + pkgdown: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Pandoc + uses: r-lib/actions/setup-pandoc@v2 + + - name: Set up R + uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - name: Install R dependencies + uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::pkgdown, local::. + needs: website + + - name: Build pkgdown site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Deploy site to gh-pages branch + uses: JamesIves/github-pages-deploy-action@v4 + with: + clean: false + branch: gh-pages + folder: docs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..234f028 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.Rproj.user +.Rhistory +.RData +.Ruserdata +docs diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..4cdcadd --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,47 @@ +Package: EFSATools +Type: Package +Title: EFSA ensemble of data collections tools +Version: 1.0.0 +Maintainer: Luca Belmonte +Authors@R: + c(person(given = "Lorenzo", + family = "Copelli", + role = "aut", + comment = c(ORCID = "0009-0002-4305-065X")), + person(given = "Luca", + family = "Belmonte", + role = c("aut", "cre"), + email = "luca.belmonte@efsa.europa.eu", + comment = c(ORCID = "0000-0002-7977-9170"))) +Description: The EFSATools package brings together all the functions developed + for EFSA's ad hoc data collections, providing tools for dataset operations as + well as utilities designed to preserve data history. +License: file LICENSE +URL: https://openefsa.github.io/EFSATools +BugReports: https://github.com/openefsa/EFSATools/issues +Depends: + R (>= 4.0.0) +Imports: + checkmate (>= 2.3.1), + dplyr (>= 1.1.4), + glue (>= 1.7.0), + rlang (>= 1.1.4), + stringr (>= 1.5.1), + tidyr (>= 1.3.1) +Suggests: + devtools (>= 2.4.5), + tibble (>= 3.3.0), + covr (>= 3.6.4), + knitr (>= 1.0), + rmarkdown (>= 2.0), + testthat (>= 3.0.0), + usethis (>= 2.2.3), + roxygen2 (>= 7.2.1) +Encoding: UTF-8 +LazyData: true +RoxygenNote: 7.3.3 +Config/testthat/edition: 3 +VignetteBuilder: knitr +Config/Needs/website: pkgdown +Repository: CRAN +Roxygen: list(markdown = TRUE) diff --git a/EFSATools.Rproj b/EFSATools.Rproj new file mode 100644 index 0000000..584b854 --- /dev/null +++ b/EFSATools.Rproj @@ -0,0 +1,19 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +BuildType: Package +PackageUseDevtools: Yes +PackageInstallArgs: --no-multiarch --with-keep.source +PackageCheckArgs: --as-cran +PackageRoxygenize: rd,collate,namespace diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c29ce2f --- /dev/null +++ b/LICENSE @@ -0,0 +1,287 @@ + EUROPEAN UNION PUBLIC LICENCE v. 1.2 + EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined +below) which is provided under the terms of this Licence. Any use of the Work, +other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). + +The Work is provided under the terms of this Licence when the Licensor (as +defined below) has placed the following notice immediately following the +copyright notice for the Work: + + Licensed under the EUPL + +or has expressed by any other means his willingness to license under the EUPL. + +1. Definitions + +In this Licence, the following terms have the following meaning: + +- ‘The Licence’: this Licence. + +- ‘The Original Work’: the work or software distributed or communicated by the + Licensor under this Licence, available as Source Code and also as Executable + Code as the case may be. + +- ‘Derivative Works’: the works or software that could be created by the + Licensee, based upon the Original Work or modifications thereof. This Licence + does not define the extent of modification or dependence on the Original Work + required in order to classify a work as a Derivative Work; this extent is + determined by copyright law applicable in the country mentioned in Article 15. + +- ‘The Work’: the Original Work or its Derivative Works. + +- ‘The Source Code’: the human-readable form of the Work which is the most + convenient for people to study and modify. + +- ‘The Executable Code’: any code which has generally been compiled and which is + meant to be interpreted by a computer as a program. + +- ‘The Licensor’: the natural or legal person that distributes or communicates + the Work under the Licence. + +- ‘Contributor(s)’: any natural or legal person who modifies the Work under the + Licence, or otherwise contributes to the creation of a Derivative Work. + +- ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of + the Work under the terms of the Licence. + +- ‘Distribution’ or ‘Communication’: any act of selling, giving, lending, + renting, distributing, communicating, transmitting, or otherwise making + available, online or offline, copies of the Work or providing access to its + essential functionalities at the disposal of any other natural or legal + person. + +2. Scope of the rights granted by the Licence + +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +sublicensable licence to do the following, for the duration of copyright vested +in the Original Work: + +- use the Work in any circumstance and for all usage, +- reproduce the Work, +- modify the Work, and make Derivative Works based upon the Work, +- communicate to the public, including the right to make available or display + the Work or copies thereof to the public and perform publicly, as the case may + be, the Work, +- distribute the Work or copies thereof, +- lend and rent the Work or copies thereof, +- sublicense rights in the Work or copies thereof. + +Those rights can be exercised on any media, supports and formats, whether now +known or later invented, as far as the applicable law permits so. + +In the countries where moral rights apply, the Licensor waives his right to +exercise his moral right to the extent allowed by law in order to make effective +the licence of the economic rights here above listed. + +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to +any patents held by the Licensor, to the extent necessary to make use of the +rights granted on the Work under this Licence. + +3. Communication of the Source Code + +The Licensor may provide the Work either in its Source Code form, or as +Executable Code. If the Work is provided as Executable Code, the Licensor +provides in addition a machine-readable copy of the Source Code of the Work +along with each copy of the Work that the Licensor distributes or indicates, in +a notice following the copyright notice attached to the Work, a repository where +the Source Code is easily and freely accessible for as long as the Licensor +continues to distribute or communicate the Work. + +4. Limitations on copyright + +Nothing in this Licence is intended to deprive the Licensee of the benefits from +any exception or limitation to the exclusive rights of the rights owners in the +Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5. Obligations of the Licensee + +The grant of the rights mentioned above is subject to some restrictions and +obligations imposed on the Licensee. Those obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or +trademarks notices and all notices that refer to the Licence and to the +disclaimer of warranties. The Licensee must include a copy of such notices and a +copy of the Licence with every copy of the Work he/she distributes or +communicates. The Licensee must cause any Derivative Work to carry prominent +notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the +Original Works or Derivative Works, this Distribution or Communication will be +done under the terms of this Licence or of a later version of this Licence +unless the Original Work is expressly distributed only under this version of the +Licence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee +(becoming Licensor) cannot offer or impose any additional terms or conditions on +the Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative +Works or copies thereof based upon both the Work and another work licensed under +a Compatible Licence, this Distribution or Communication can be done under the +terms of this Compatible Licence. For the sake of this clause, ‘Compatible +Licence’ refers to the licences listed in the appendix attached to this Licence. +Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible +Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, +the Licensee will provide a machine-readable copy of the Source Code or indicate +a repository where this Source will be easily and freely available for as long +as the Licensee continues to distribute or communicate the Work. + +Legal Protection: This Licence does not grant permission to use the trade names, +trademarks, service marks, or names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6. Chain of Authorship + +The original Licensor warrants that the copyright in the Original Work granted +hereunder is owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each Contributor warrants that the copyright in the modifications he/she brings +to the Work are owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each time You accept the Licence, the original Licensor and subsequent +Contributors grant You a licence to their contributions to the Work, under the +terms of this Licence. + +7. Disclaimer of Warranty + +The Work is a work in progress, which is continuously improved by numerous +Contributors. It is not a finished work and may therefore contain defects or +‘bugs’ inherent to this type of development. + +For the above reason, the Work is provided under the Licence on an ‘as is’ basis +and without warranties of any kind concerning the Work, including without +limitation merchantability, fitness for a particular purpose, absence of defects +or errors, accuracy, non-infringement of intellectual property rights other than +copyright as stated in Article 6 of this Licence. + +This disclaimer of warranty is an essential part of the Licence and a condition +for the grant of any rights to the Work. + +8. Disclaimer of Liability + +Except in the cases of wilful misconduct or damages directly caused to natural +persons, the Licensor will in no event be liable for any direct or indirect, +material or moral, damages of any kind, arising out of the Licence or of the use +of the Work, including without limitation, damages for loss of goodwill, work +stoppage, computer failure or malfunction, loss of data or any commercial +damage, even if the Licensor has been advised of the possibility of such damage. +However, the Licensor will be liable under statutory product liability laws as +far such laws apply to the Work. + +9. Additional agreements + +While distributing the Work, You may choose to conclude an additional agreement, +defining obligations or services consistent with this Licence. However, if +accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, +and only if You agree to indemnify, defend, and hold each Contributor harmless +for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +10. Acceptance of the Licence + +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ +placed under the bottom of a window displaying the text of this Licence or by +affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable +acceptance of this Licence and all of its terms and conditions. + +Similarly, you irrevocably accept this Licence and all of its terms and +conditions by exercising any rights granted to You by Article 2 of this Licence, +such as the use of the Work, the creation by You of a Derivative Work or the +Distribution or Communication by You of the Work or copies thereof. + +11. Information to the public + +In case of any Distribution or Communication of the Work by means of electronic +communication by You (for example, by offering to download the Work from a +remote location) the distribution channel or media (for example, a website) must +at least provide to the public the information requested by the applicable law +regarding the Licensor, the Licence and the way it may be accessible, concluded, +stored and reproduced by the Licensee. + +12. Termination of the Licence + +The Licence and the rights granted hereunder will terminate automatically upon +any breach by the Licensee of the terms of the Licence. + +Such a termination will not terminate the licences of any person who has +received the Work from the Licensee under the Licence, provided such persons +remain in full compliance with the Licence. + +13. Miscellaneous + +Without prejudice of Article 9 above, the Licence represents the complete +agreement between the Parties as to the Work. + +If any provision of the Licence is invalid or unenforceable under applicable +law, this will not affect the validity or enforceability of the Licence as a +whole. Such provision will be construed or reformed so as necessary to make it +valid and enforceable. + +The European Commission may publish other linguistic versions or new versions of +this Licence or updated versions of the Appendix, so far this is required and +reasonable, without reducing the scope of the rights granted by the Licence. New +versions of the Licence will be published with a unique version number. + +All linguistic versions of this Licence, approved by the European Commission, +have identical value. Parties can take advantage of the linguistic version of +their choice. + +14. Jurisdiction + +Without prejudice to specific agreement between parties, + +- any litigation resulting from the interpretation of this License, arising + between the European Union institutions, bodies, offices or agencies, as a + Licensor, and any Licensee, will be subject to the jurisdiction of the Court + of Justice of the European Union, as laid down in article 272 of the Treaty on + the Functioning of the European Union, + +- any litigation arising between other parties and resulting from the + interpretation of this License, will be subject to the exclusive jurisdiction + of the competent court where the Licensor resides or conducts its primary + business. + +15. Applicable Law + +Without prejudice to specific agreement between parties, + +- this Licence shall be governed by the law of the European Union Member State + where the Licensor has his seat, resides or has his registered office, + +- this licence shall be governed by Belgian law if the Licensor has no seat, + residence or registered office inside a European Union Member State. + +Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: + +- GNU General Public License (GPL) v. 2, v. 3 +- GNU Affero General Public License (AGPL) v. 3 +- Open Software License (OSL) v. 2.1, v. 3.0 +- Eclipse Public License (EPL) v. 1.0 +- CeCILL v. 2.0, v. 2.1 +- Mozilla Public Licence (MPL) v. 2 +- GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +- Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for + works other than software +- European Union Public Licence (EUPL) v. 1.1, v. 1.2 +- Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong + Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above +licences without producing a new version of the EUPL, as long as they provide +the rights granted in Article 2 of this Licence and protect the covered Source +Code from exclusive appropriation. + +All other changes or additions to this Appendix require the production of a new +EUPL version. \ No newline at end of file diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 0000000..23beaea --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,33 @@ +# Generated by roxygen2: do not edit by hand + +export(SCD2) +export(SSCD2) +export(dropEmpty) +export(enrich) +export(removeReplicatedColumns) +importFrom(checkmate,assert_data_frame) +importFrom(checkmate,assert_names) +importFrom(checkmate,assert_string) +importFrom(checkmate,assert_vector) +importFrom(dplyr,across) +importFrom(dplyr,anti_join) +importFrom(dplyr,any_of) +importFrom(dplyr,bind_cols) +importFrom(dplyr,bind_rows) +importFrom(dplyr,filter) +importFrom(dplyr,inner_join) +importFrom(dplyr,left_join) +importFrom(dplyr,mutate) +importFrom(dplyr,mutate_all) +importFrom(dplyr,na_if) +importFrom(dplyr,right_join) +importFrom(dplyr,select) +importFrom(dplyr,starts_with) +importFrom(dplyr,where) +importFrom(glue,glue) +importFrom(rlang,":=") +importFrom(rlang,.data) +importFrom(rlang,sym) +importFrom(stringr,regex) +importFrom(stringr,str_replace_all) +importFrom(tidyr,unite) diff --git a/R/EFSATools-package.R b/R/EFSATools-package.R new file mode 100644 index 0000000..a65cf64 --- /dev/null +++ b/R/EFSATools-package.R @@ -0,0 +1,6 @@ +#' @keywords internal +"_PACKAGE" + +## usethis namespace: start +## usethis namespace: end +NULL diff --git a/R/SCD2.R b/R/SCD2.R new file mode 100644 index 0000000..0f53f74 --- /dev/null +++ b/R/SCD2.R @@ -0,0 +1,66 @@ +#' Implement a Slowly Changing Dimension Type 2. +#' +#' This function implements a Slowly Changing Dimension Type 2 to merge new and +#' current data while maintaining historical records. The function deactivates +#' the old records and activates new ones, ensuring a history-preserving update +#' strategy. Only the changing records are marked as not active and replaced by +#' new active ones. +#' +#' @param newData `data.frame`. The data frame containing new records. +#' +#' @param currentData `data.frame`. The data frame containing existing records. +#' +#' @param key `character` (vector). The columns to be used as key. +#' +#' @return A combined data frame with old data marked as not active and new data +#' marked as active. +#' +#' @importFrom checkmate assert_data_frame assert_vector +#' @importFrom dplyr bind_rows inner_join right_join anti_join +#' +#' @details +#' The function: +#' 1. Separates active and inactive records from the current data. +#' 2. Gets the old records that are still present in the new data (i.e., +#' the ones that can remain active). +#' 3. Gets the records present in new data but not present in still active +#' current data (i.e., the records to activate) and activates them. +#' 4. Gets the current active records that are not present in the new data +#' (i.e., the records to deactivate) and deactivates them. +#' +#' @examplesIf FALSE +#' mergedData <- SCD2(newData = iris, currentData = iris) +#' +#' @export +#' +SCD2 <- function(newData, currentData, key = names(newData)) { + + assert_data_frame(newData) + assert_data_frame(currentData) + assert_vector(key) + + currentInactiveData_ <- currentData |> + filter(IS_ACTIVE = FALSE) + + currentActiveData_ <- currentData |> + filter(IS_ACTIVE = TRUE) + + stillActiveData_ <- inner_join( + unique(currentActiveData_), + unique(newData), + by = key) + + newlyActiveData_ <- anti_join(newData, currentActiveData_, by = key) + newlyActiveData_ <- .activate(dataframe = newlyActiveData_) + + deactivatedData_ <- anti_join(currentActiveData_, newData, by = key) + deactivatedData_ <- .deactivate(dataframe = deactivatedData_) + + mergedData_ <- bind_rows( + stillActiveData_, + newlyActiveData_, + deactivatedData_, + currentInactiveData_) + + return(mergedData_) +} diff --git a/R/SSCD2.R b/R/SSCD2.R new file mode 100644 index 0000000..6c6887f --- /dev/null +++ b/R/SSCD2.R @@ -0,0 +1,36 @@ +#' Implement a "Simple" Slowly Changing Dimension Type 2. +#' +#' This function implements a Simplified version of Slowly Changing Dimension +#' Type 2 to merge new and current data while maintaining historical records. +#' The function deactivates all the old records and activates new ones, ensuring +#' a history-preserving update strategy. The difference between a standard SCD2 +#' is that this simplified version applies no checks on the data, deactivating +#' all the old records and activating the new ones, even if some of the old +#' records are still active. +#' +#' @param newData `data.frame`. The data frame containing new records. +#' +#' @param currentData `data.frame`. The data frame containing existing records. +#' +#' @return A combined data frame with all old data marked as not active and new +#' data marked as active. +#' +#' @importFrom checkmate assert_data_frame +#' @importFrom dplyr bind_rows +#' +#' @examplesIf FALSE +#' mergedData <- SSCD2(newData = iris, currentData = iris) +#' +#' @export +#' +SSCD2 <- function(newData, currentData) { + + assert_data_frame(newData) + assert_data_frame(currentData) + + mergedData_ <- bind_rows( + .deactivate(currentData), + .activate(newData)) + + return(mergedData_) +} diff --git a/R/activate.R b/R/activate.R new file mode 100644 index 0000000..6a4e84e --- /dev/null +++ b/R/activate.R @@ -0,0 +1,31 @@ +#' Activate the records of the specified data frame. +#' +#' This helper function is used in the context of a Slowly Changing Dimension +#' (SCD) to mark new records of a data frame as active with a start date. +#' +#' @param dataframe `data.frame`. The data frame to activate. +#' +#' @return The specified data frame with ACTIVE set to TRUE, START_DATE set to +#' current time, and END_DATE set to NA. +#' +#' @importFrom checkmate assert_data_frame +#' @importFrom dplyr mutate +#' +#' @examplesIf FALSE +#' activatedDataframe <- .activate(dataframe = dataframe) +#' +#' @keywords internal +#' @noRd +#' +.activate <- function(dataframe) { + + assert_data_frame(dataframe) + + activatedDataframe_ <- dataframe |> mutate( + IS_ACTIVE = TRUE, + START_DATE = Sys.time(), + END_DATE = as.Date(NA) + ) + + return(activatedDataframe_) +} diff --git a/R/deactivate.R b/R/deactivate.R new file mode 100644 index 0000000..fc4051c --- /dev/null +++ b/R/deactivate.R @@ -0,0 +1,30 @@ +#' Deactivate the records of the specified data frame. +#' +#' This helper function is used in the context of a Slowly Changing Dimension +#' (SCD) to mark active records of a data frame as not active with an end date. +#' +#' @param dataframe `data.frame`. The data frame to deactivate. +#' +#' @return The specified data frame with IS_ACTIVE set to FALSE and END_DATE set +#' to current time. +#' +#' @importFrom checkmate assert_data_frame +#' @importFrom dplyr mutate +#' +#' @examplesIf FALSE +#' deactivatedDataframe <- .deactivate(dataframe = dataframe) +#' +#' @keywords internal +#' @noRd +#' +.deactivate <- function(dataframe) { + + assert_data_frame(dataframe) + + deactivatedDataframe_ <- dataframe |> mutate( + IS_ACTIVE = FALSE, + END_DATE = Sys.time() + ) + + return(deactivatedDataframe_) +} diff --git a/R/dropEmpty.R b/R/dropEmpty.R new file mode 100644 index 0000000..29ffc4d --- /dev/null +++ b/R/dropEmpty.R @@ -0,0 +1,38 @@ +#' Drop empty lines and columns from the specified data frame. +#' +#' This function drops all the empty lines and columns from the specified data +#' frame, i.e. all the rows and columns that contain only NAs. +#' +#' @param dataframe `data.frame`. The data frame from which to remove the empty +#' lines and columns. +#' +#' @return The provided data frame without empty lines and columns and all the +#' types transformed to string. +#' +#' @importFrom checkmate assert_data_frame +#' @importFrom dplyr filter select where mutate_all +#' +#' @examplesIf FALSE +#' # The first row is going to be dropped. +#' iris[1, ] <- NA +#' iris <- dropEmpty(iris) +#' +#' # The Species column is going to be dropped. +#' iris$Species <- NA +#' iris <- dropEmpty(iris) +#' +#' @export +#' +dropEmpty <- function(dataframe) { + + assert_data_frame(dataframe) + + rowSum_ <- rowSums(is.na(dataframe)) + + dataframe <- dataframe |> + filter(rowSum_ != ncol(dataframe)) |> + select(where(~ !all(is.na(.)))) |> + mutate_all(as.character) + + return(dataframe) +} diff --git a/R/enrich.R b/R/enrich.R new file mode 100644 index 0000000..b1cde48 --- /dev/null +++ b/R/enrich.R @@ -0,0 +1,56 @@ +#' Enrich a data frame with an EFSA catalogue. +#' +#' This function takes a data frame and joins it with an EFSA catalog. The EFSA +#' catalog must be itself a data frame. +#' +#' @param dataframe `data.frame`. The data frame to be enriched. +#' +#' @param catalogue `data.frame`. The data frame that contains the EFSA +#' catalogue to be used for the enrichment. It must contain at least two +#' columns, namely: NAME and CODE. +#' +#' @param joinBy `character` (string). The variable to be used as the join key. +#' +#' @param enrichedColumnName `character` (string). The name of the column added +#' to the original data. +#' +#' @return The specified data frame enriched with the catalogue data. +#' +#' @importFrom checkmate assert_data_frame assert_names assert_string +#' @importFrom dplyr select mutate left_join +#' @importFrom rlang .data := +#' +#' @examplesIf FALSE +#' dataframe_ <- iris |> dplyr::rename(CODE = Species) +#' +#' catalogue_ <- iris |> +#' dplyr::rename(CODE = Species) |> +#' dplyr::mutate(NAME = "data") |> +#' dplyr::select(CODE, NAME) |> +#' unique() +#' +#' enriched_ <- enrich( +#' dataframe = dataframe_, +#' catalogue = catalogue_, +#' joinBy = "CODE", +#' enrichedColumnName = "enrichedColumn") +#' +#' @export +#' +enrich <- function(dataframe, catalogue, joinBy, enrichedColumnName) { + + assert_data_frame(dataframe) + assert_data_frame(catalogue) + assert_names(names(catalogue), must.include = c("NAME", "CODE")) + assert_string(joinBy) + assert_string(enrichedColumnName) + + catalogue <- catalogue |> + select("NAME", "CODE") |> + mutate(!!joinBy := .data$CODE) + + enriched_ <- left_join(dataframe, catalogue, by = joinBy) |> + select(!!enrichedColumnName := "NAME", names(dataframe)) + + return(enriched_) +} diff --git a/R/removeReplicatedColumns.R b/R/removeReplicatedColumns.R new file mode 100644 index 0000000..4aba464 --- /dev/null +++ b/R/removeReplicatedColumns.R @@ -0,0 +1,78 @@ +#' Drop and merge replicated columns from the specified data frame. +#' +#' This function drops and merges all the replicated columns from the specified +#' data frame. +#' +#' @param dataframe `data.frame`. The data frame from which to drop the +#' replicated columns. +#' +#' @param prefix `character` (string). The prefix with which the name of the +#' replicated columns starts. +#' +#' @returns The specified data frame with an additional deduplicated column and +#' all the types transformed to string. +#' +#' @importFrom dplyr mutate across starts_with select bind_cols na_if any_of +#' @importFrom tidyr unite +#' @importFrom stringr str_replace_all regex +#' @importFrom glue glue +#' @importFrom checkmate assert_data_frame assert_string +#' @importFrom rlang := sym +#' +#' @details +#' All the occurrences of "N/A", "NA", and empty strings (case insensitive) +#' inside the provided data frame are replaced with NAs of type character. +#' Then, all and only the columns starting with the specified prefix are +#' selected and united into a single column with name ending per +#' "_deduplicated". All empty entries in the new deduplicated column are +#' replaced with NAs. Finally, the new column is bound with the other columns of +#' the initial dataframe. +#' +#' @examplesIf FALSE +#' iris$Species_1 <- iris$Species +#' iris$Species_2 <- iris$Species +#' iris$Species <- NULL +#' +#' deduplicatedDataframe_ <- removeReplicatedColumns( +#' dataframe = iris, +#' prefix = "Species_") +#' +#' @export +#' +removeReplicatedColumns <- function(dataframe, prefix) { + + assert_data_frame(dataframe) + assert_string(prefix) + + dataframe <- dataframe |> + + mutate(across(starts_with(prefix), as.character)) |> + + mutate(across(starts_with(prefix), + \(x) str_replace_all( + x, + regex("^N/a$|^Na$|^$", ignore_case = TRUE), + NA_character_))) + + dataframe_prefix_columns_ <- dataframe |> + select(starts_with(prefix)) + + dataframe_prefix_columns_ <- dataframe_prefix_columns_ |> + + unite(!!glue("{prefix}_deduplicated"), + 1:ncol(dataframe_prefix_columns_), + sep = "", + na.rm = TRUE) |> + + mutate(!!glue("{prefix}_deduplicated") + := na_if(!!sym(glue("{prefix}_deduplicated")), "")) |> + + bind_cols( + dataframe |> + select(-starts_with(prefix)) |> + select(any_of(names(dataframe)))) |> + + mutate_all(as.character) + + return(dataframe_prefix_columns_) +} diff --git a/README.md b/README.md index cec48bd..efb5377 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,45 @@ -# EFSATools -EFSA ensemble of data collections tools. +# EFSATools + +[![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) [![codecov](https://codecov.io/gh/openefsa/EFSATools/branch/main/graph/badge.svg?token=X2HZIV0B1D)](https://codecov.io/gh/openefsa/EFSATools) + +## Overview + +The **EFSATools** package brings together all the functions developed for EFSA's ad hoc data collections, providing tools for dataset operations as well as utilities designed to preserve data history. + +The package is intended for researchers, analysts, and practitioners who require convenient programmatic access to data collection utilities. + +## Installation + +### From CRAN + +```r +install.packages("EFSATools") +``` + +### Development version (from GitHub) + +To install the latest development version: + +```r +# install.packages("devtools") +devtools::install_github("openefsa/EFSATools") +``` + +## Usage + +Once installed, load the package as usual: + +```r +library(EFSATools) +``` + +Basic usage examples and full documentation are available in the package [vignette](vignettes/EFSATools.Rmd): + +```r +vignette("EFSATools") +``` + +## Links + +- **Source code:** [GitHub – openefsa/EFSATools](https://github.com/openefsa/EFSATools) +- **Bug reports:** [Issues on GitHub](https://github.com/openefsa/EFSATools/issues) \ No newline at end of file diff --git a/_pkgdown.yml b/_pkgdown.yml new file mode 100644 index 0000000..107bd78 --- /dev/null +++ b/_pkgdown.yml @@ -0,0 +1,8 @@ +template: + bootstrap: 5 + +development: + mode: auto + +url: https://openefsa.github.io/EFSATools +destination: docs diff --git a/man/EFSATools-package.Rd b/man/EFSATools-package.Rd new file mode 100644 index 0000000..e45f452 --- /dev/null +++ b/man/EFSATools-package.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/EFSATools-package.R +\docType{package} +\name{EFSATools-package} +\alias{EFSATools} +\alias{EFSATools-package} +\title{EFSATools: EFSA ensemble of data collections tools} +\description{ +\if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}} + +The EFSATools package brings together all the functions developed for EFSA's ad hoc data collections, providing tools for dataset operations as well as utilities designed to preserve data history. +} +\seealso{ +Useful links: +\itemize{ + \item \url{https://openefsa.github.io/EFSATools} + \item Report bugs at \url{https://github.com/openefsa/EFSATools/issues} +} + +} +\author{ +\strong{Maintainer}: Luca Belmonte \email{luca.belmonte@efsa.europa.eu} (\href{https://orcid.org/0000-0002-7977-9170}{ORCID}) + +Authors: +\itemize{ + \item Lorenzo Copelli (\href{https://orcid.org/0009-0002-4305-065X}{ORCID}) +} + +} +\keyword{internal} diff --git a/man/SCD2.Rd b/man/SCD2.Rd new file mode 100644 index 0000000..cf67afe --- /dev/null +++ b/man/SCD2.Rd @@ -0,0 +1,43 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/SCD2.R +\name{SCD2} +\alias{SCD2} +\title{Implement a Slowly Changing Dimension Type 2.} +\usage{ +SCD2(newData, currentData, key = names(newData)) +} +\arguments{ +\item{newData}{\code{data.frame}. The data frame containing new records.} + +\item{currentData}{\code{data.frame}. The data frame containing existing records.} + +\item{key}{\code{character} (vector). The columns to be used as key.} +} +\value{ +A combined data frame with old data marked as not active and new data +marked as active. +} +\description{ +This function implements a Slowly Changing Dimension Type 2 to merge new and +current data while maintaining historical records. The function deactivates +the old records and activates new ones, ensuring a history-preserving update +strategy. Only the changing records are marked as not active and replaced by +new active ones. +} +\details{ +The function: +\enumerate{ +\item Separates active and inactive records from the current data. +\item Gets the old records that are still present in the new data (i.e., +the ones that can remain active). +\item Gets the records present in new data but not present in still active +current data (i.e., the records to activate) and activates them. +\item Gets the current active records that are not present in the new data +(i.e., the records to deactivate) and deactivates them. +} +} +\examples{ +\dontshow{if (FALSE) withAutoprint(\{ # examplesIf} +mergedData <- SCD2(newData = iris, currentData = iris) +\dontshow{\}) # examplesIf} +} diff --git a/man/SSCD2.Rd b/man/SSCD2.Rd new file mode 100644 index 0000000..dea4a39 --- /dev/null +++ b/man/SSCD2.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/SSCD2.R +\name{SSCD2} +\alias{SSCD2} +\title{Implement a "Simple" Slowly Changing Dimension Type 2.} +\usage{ +SSCD2(newData, currentData) +} +\arguments{ +\item{newData}{\code{data.frame}. The data frame containing new records.} + +\item{currentData}{\code{data.frame}. The data frame containing existing records.} +} +\value{ +A combined data frame with all old data marked as not active and new +data marked as active. +} +\description{ +This function implements a Simplified version of Slowly Changing Dimension +Type 2 to merge new and current data while maintaining historical records. +The function deactivates all the old records and activates new ones, ensuring +a history-preserving update strategy. The difference between a standard SCD2 +is that this simplified version applies no checks on the data, deactivating +all the old records and activating the new ones, even if some of the old +records are still active. +} +\examples{ +\dontshow{if (FALSE) withAutoprint(\{ # examplesIf} +mergedData <- SSCD2(newData = iris, currentData = iris) +\dontshow{\}) # examplesIf} +} diff --git a/man/dropEmpty.Rd b/man/dropEmpty.Rd new file mode 100644 index 0000000..7160bde --- /dev/null +++ b/man/dropEmpty.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/dropEmpty.R +\name{dropEmpty} +\alias{dropEmpty} +\title{Drop empty lines and columns from the specified data frame.} +\usage{ +dropEmpty(dataframe) +} +\arguments{ +\item{dataframe}{\code{data.frame}. The data frame from which to remove the empty +lines and columns.} +} +\value{ +The provided data frame without empty lines and columns and all the +types transformed to string. +} +\description{ +This function drops all the empty lines and columns from the specified data +frame, i.e. all the rows and columns that contain only NAs. +} +\examples{ +\dontshow{if (FALSE) withAutoprint(\{ # examplesIf} +# The first row is going to be dropped. +iris[1, ] <- NA +iris <- dropEmpty(iris) + +# The Species column is going to be dropped. +iris$Species <- NA +iris <- dropEmpty(iris) +\dontshow{\}) # examplesIf} +} diff --git a/man/enrich.Rd b/man/enrich.Rd new file mode 100644 index 0000000..ef02c2a --- /dev/null +++ b/man/enrich.Rd @@ -0,0 +1,44 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/enrich.R +\name{enrich} +\alias{enrich} +\title{Enrich a data frame with an EFSA catalogue.} +\usage{ +enrich(dataframe, catalogue, joinBy, enrichedColumnName) +} +\arguments{ +\item{dataframe}{\code{data.frame}. The data frame to be enriched.} + +\item{catalogue}{\code{data.frame}. The data frame that contains the EFSA +catalogue to be used for the enrichment. It must contain at least two +columns, namely: NAME and CODE.} + +\item{joinBy}{\code{character} (string). The variable to be used as the join key.} + +\item{enrichedColumnName}{\code{character} (string). The name of the column added +to the original data.} +} +\value{ +The specified data frame enriched with the catalogue data. +} +\description{ +This function takes a data frame and joins it with an EFSA catalog. The EFSA +catalog must be itself a data frame. +} +\examples{ +\dontshow{if (FALSE) withAutoprint(\{ # examplesIf} +dataframe_ <- iris |> dplyr::rename(CODE = Species) + +catalogue_ <- iris |> + dplyr::rename(CODE = Species) |> + dplyr::mutate(NAME = "data") |> + dplyr::select(CODE, NAME) |> + unique() + +enriched_ <- enrich( + dataframe = dataframe_, + catalogue = catalogue_, + joinBy = "CODE", + enrichedColumnName = "enrichedColumn") +\dontshow{\}) # examplesIf} +} diff --git a/man/figures/logo.png b/man/figures/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8bbfcbfd26b09b73c6270bb682d2cae6452c68ce GIT binary patch literal 79480 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%0DcOH57WRO=Vs z4D5+L=9ZSjk7Rk%XJ>W1uFmGh)`p&RB+V2L!| z@3eNM7*ha!$SF^m%gvr@ryH_V^yN-urWmpv| zrNP2D?q$S#t*}Id>`GhNxy28 z9`+tKXJfY<_pPd`g2BG8b$|QjoAq#oXU?qkl%eO~LEsayth?{Sg&8v*lg_aH`qeZW z{``0S*RKRkrz6G2^zwFUv7cn1EjiMO{ey$=7uv%XmU|LyxsxM{y=*7nb6&MN@YWi% z^;YBSt>tMLt||?C1U)f+rxwx@GYfUK9ePf?tW~IDfLI^d7tC-?Y5)22Zf`0-llqU7 z*bDShGf}$2K=J@LG(Kj^0QGNrN5A*y0^_JZFUaZWeAd0(i@PT|?6_#pB_S!fJMT~S zJ2UK+poa$!D^choGj6Eui!j%n)T?df^GhF{Z~f(Vw{GfjKfNocpThTY!TyNFRr`A} zQ;fu?rLH)GwZUvT*r4Vu&d)8YtJJ`A-m)iVN920-jMuun6vuhpZIDYY@&LQVftPfe z^j!~m(d(@P$5$`0*+@d)d|_v@P>)Hv^@y6&7h!7>7_zMCq_nMZ%kIA zBM^wMo+r!z!Z2G-dN-w73+9g>t~?*fk|mUSTRb94kTiSA{yN|ZPROsrk=N5T+?4C2 zm4+SI1zI)OM4^C4rPH_=?#rS_RX+~{{9CbA<-*UdmfQn?LF|BgM*DCTNw3RZ@Pv(z#{Ip z?NQL$)CWG)U?U5<5_2IEjW{L2>>M=Q*WqFhg|WYv+>fT6_e!*Pa42=zp4|@Rj8n)( zLqiKsP7dwtl+bGQB&3o}5eBOm&)T^xHeba%WO~2WZmAUHw+68}{p{{dd*t`TIA99* z8$z=0mh9Ss8)<86tLuIbM?_Rq)L}avsU2gCFv+nS�yOdzDmAWv5h*kL9}4?GsT* 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 literal 0 HcmV?d00001 diff --git a/pkgdown/favicon/favicon.svg b/pkgdown/favicon/favicon.svg new file mode 100644 index 0000000..40776e4 --- /dev/null +++ b/pkgdown/favicon/favicon.svg @@ -0,0 +1 @@ +RealFaviconGeneratorhttps://realfavicongenerator.net \ No newline at end of file diff --git a/pkgdown/favicon/site.webmanifest b/pkgdown/favicon/site.webmanifest new file mode 100644 index 0000000..4ebda26 --- /dev/null +++ b/pkgdown/favicon/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/pkgdown/favicon/web-app-manifest-192x192.png b/pkgdown/favicon/web-app-manifest-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..12009c4bcd2b19be5da942413a9d6d85bb0044b2 GIT binary patch literal 11220 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
Fihh;`zrq)<*?fA)g&30&*6L=gqquRAAoMd9 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 Reading from a connection which does not supply a 'gzip' magic + # > header is equivalent to reading from the original connection + conn <- gzcon(file(bundle, open = "rb", raw = TRUE)) + on.exit(close(conn)) + + # The default pax header is 512 bytes long and the first pax extended header + # with the comment should be 51 bytes long + # `52 comment=` (11 chars) + 40 byte SHA1 hash + len <- 0x200 + 0x33 + res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len]) + + if (grepl("^52 comment=", res)) { + sub("52 comment=", "", res) + } else { + NULL + } + } + + renv_bootstrap_install <- function(version, tarball, library) { + + # attempt to install it into project library + dir.create(library, showWarnings = FALSE, recursive = TRUE) + output <- renv_bootstrap_install_impl(library, tarball) + + # check for successful install + status <- attr(output, "status") + if (is.null(status) || identical(status, 0L)) + return(status) + + # an error occurred; report it + header <- "installation of renv failed" + lines <- paste(rep.int("=", nchar(header)), collapse = "") + text <- paste(c(header, lines, output), collapse = "\n") + stop(text) + + } + + renv_bootstrap_install_impl <- function(library, tarball) { + + # invoke using system2 so we can capture and report output + bin <- R.home("bin") + exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" + R <- file.path(bin, exe) + + args <- c( + "--vanilla", "CMD", "INSTALL", "--no-multiarch", + "-l", shQuote(path.expand(library)), + shQuote(path.expand(tarball)) + ) + + system2(R, args, stdout = TRUE, stderr = TRUE) + + } + + renv_bootstrap_platform_prefix <- function() { + + # construct version prefix + version <- paste(R.version$major, R.version$minor, sep = ".") + prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-") + + # include SVN revision for development versions of R + # (to avoid sharing platform-specific artefacts with released versions of R) + devel <- + identical(R.version[["status"]], "Under development (unstable)") || + identical(R.version[["nickname"]], "Unsuffered Consequences") + + if (devel) + prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r") + + # build list of path components + components <- c(prefix, R.version$platform) + + # include prefix if provided by user + prefix <- renv_bootstrap_platform_prefix_impl() + if (!is.na(prefix) && nzchar(prefix)) + components <- c(prefix, components) + + # build prefix + paste(components, collapse = "/") + + } + + renv_bootstrap_platform_prefix_impl <- function() { + + # if an explicit prefix has been supplied, use it + prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA) + if (!is.na(prefix)) + return(prefix) + + # if the user has requested an automatic prefix, generate it + auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) + if (auto %in% c("TRUE", "True", "true", "1")) + return(renv_bootstrap_platform_prefix_auto()) + + # empty string on failure + "" + + } + + renv_bootstrap_platform_prefix_auto <- function() { + + prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity) + if (inherits(prefix, "error") || prefix %in% "unknown") { + + msg <- paste( + "failed to infer current operating system", + "please file a bug report at https://github.com/rstudio/renv/issues", + sep = "; " + ) + + warning(msg) + + } + + prefix + + } + + renv_bootstrap_platform_os <- function() { + + sysinfo <- Sys.info() + sysname <- sysinfo[["sysname"]] + + # handle Windows + macOS up front + if (sysname == "Windows") + return("windows") + else if (sysname == "Darwin") + return("macos") + + # check for os-release files + for (file in c("/etc/os-release", "/usr/lib/os-release")) + if (file.exists(file)) + return(renv_bootstrap_platform_os_via_os_release(file, sysinfo)) + + # check for redhat-release files + if (file.exists("/etc/redhat-release")) + return(renv_bootstrap_platform_os_via_redhat_release()) + + "unknown" + + } + + renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) { + + # read /etc/os-release + release <- utils::read.table( + file = file, + sep = "=", + quote = c("\"", "'"), + col.names = c("Key", "Value"), + comment.char = "#", + stringsAsFactors = FALSE + ) + + vars <- as.list(release$Value) + names(vars) <- release$Key + + # get os name + os <- tolower(sysinfo[["sysname"]]) + + # read id + id <- "unknown" + for (field in c("ID", "ID_LIKE")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + id <- vars[[field]] + break + } + } + + # read version + version <- "unknown" + for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + version <- vars[[field]] + break + } + } + + # join together + paste(c(os, id, version), collapse = "-") + + } + + renv_bootstrap_platform_os_via_redhat_release <- function() { + + # read /etc/redhat-release + contents <- readLines("/etc/redhat-release", warn = FALSE) + + # infer id + id <- if (grepl("centos", contents, ignore.case = TRUE)) + "centos" + else if (grepl("redhat", contents, ignore.case = TRUE)) + "redhat" + else + "unknown" + + # try to find a version component (very hacky) + version <- "unknown" + + parts <- strsplit(contents, "[[:space:]]")[[1L]] + for (part in parts) { + + nv <- tryCatch(numeric_version(part), error = identity) + if (inherits(nv, "error")) + next + + version <- nv[1, 1] + break + + } + + paste(c("linux", id, version), collapse = "-") + + } + + renv_bootstrap_library_root_name <- function(project) { + + # use project name as-is if requested + asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE") + if (asis) + return(basename(project)) + + # otherwise, disambiguate based on project's path + id <- substring(renv_bootstrap_hash_text(project), 1L, 8L) + paste(basename(project), id, sep = "-") + + } + + renv_bootstrap_library_root <- function(project) { + + prefix <- renv_bootstrap_profile_prefix() + + path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA) + if (!is.na(path)) + return(paste(c(path, prefix), collapse = "/")) + + path <- renv_bootstrap_library_root_impl(project) + if (!is.null(path)) { + name <- renv_bootstrap_library_root_name(project) + return(paste(c(path, prefix, name), collapse = "/")) + } + + renv_bootstrap_paths_renv("library", project = project) + + } + + renv_bootstrap_library_root_impl <- function(project) { + + root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA) + if (!is.na(root)) + return(root) + + type <- renv_bootstrap_project_type(project) + if (identical(type, "package")) { + userdir <- renv_bootstrap_user_dir() + return(file.path(userdir, "library")) + } + + } + + renv_bootstrap_validate_version <- function(version, description = NULL) { + + # resolve description file + # + # avoid passing lib.loc to `packageDescription()` below, since R will + # use the loaded version of the package by default anyhow. note that + # this function should only be called after 'renv' is loaded + # https://github.com/rstudio/renv/issues/1625 + description <- description %||% packageDescription("renv") + + # check whether requested version 'version' matches loaded version of renv + sha <- attr(version, "sha", exact = TRUE) + valid <- if (!is.null(sha)) + renv_bootstrap_validate_version_dev(sha, description) + else + renv_bootstrap_validate_version_release(version, description) + + if (valid) + return(TRUE) + + # the loaded version of renv doesn't match the requested version; + # give the user instructions on how to proceed + remote <- if (!is.null(description[["RemoteSha"]])) { + paste("rstudio/renv", description[["RemoteSha"]], sep = "@") + } else { + paste("renv", description[["Version"]], sep = "@") + } + + # display both loaded version + sha if available + friendly <- renv_bootstrap_version_friendly( + version = description[["Version"]], + sha = description[["RemoteSha"]] + ) + + fmt <- paste( + "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.", + "- Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", + "- Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", + sep = "\n" + ) + catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote) + + FALSE + + } + + renv_bootstrap_validate_version_dev <- function(version, description) { + expected <- description[["RemoteSha"]] + is.character(expected) && startswith(expected, version) + } + + renv_bootstrap_validate_version_release <- function(version, description) { + expected <- description[["Version"]] + is.character(expected) && identical(expected, version) + } + + renv_bootstrap_hash_text <- function(text) { + + hashfile <- tempfile("renv-hash-") + on.exit(unlink(hashfile), add = TRUE) + + writeLines(text, con = hashfile) + tools::md5sum(hashfile) + + } + + renv_bootstrap_load <- function(project, libpath, version) { + + # try to load renv from the project library + if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) + return(FALSE) + + # warn if the version of renv loaded does not match + renv_bootstrap_validate_version(version) + + # execute renv load hooks, if any + hooks <- getHook("renv::autoload") + for (hook in hooks) + if (is.function(hook)) + tryCatch(hook(), error = warnify) + + # load the project + renv::load(project) + + TRUE + + } + + renv_bootstrap_profile_load <- function(project) { + + # if RENV_PROFILE is already set, just use that + profile <- Sys.getenv("RENV_PROFILE", unset = NA) + if (!is.na(profile) && nzchar(profile)) + return(profile) + + # check for a profile file (nothing to do if it doesn't exist) + path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project) + if (!file.exists(path)) + return(NULL) + + # read the profile, and set it if it exists + contents <- readLines(path, warn = FALSE) + if (length(contents) == 0L) + return(NULL) + + # set RENV_PROFILE + profile <- contents[[1L]] + if (!profile %in% c("", "default")) + Sys.setenv(RENV_PROFILE = profile) + + profile + + } + + renv_bootstrap_profile_prefix <- function() { + profile <- renv_bootstrap_profile_get() + if (!is.null(profile)) + return(file.path("profiles", profile, "renv")) + } + + renv_bootstrap_profile_get <- function() { + profile <- Sys.getenv("RENV_PROFILE", unset = "") + renv_bootstrap_profile_normalize(profile) + } + + renv_bootstrap_profile_set <- function(profile) { + profile <- renv_bootstrap_profile_normalize(profile) + if (is.null(profile)) + Sys.unsetenv("RENV_PROFILE") + else + Sys.setenv(RENV_PROFILE = profile) + } + + renv_bootstrap_profile_normalize <- function(profile) { + + if (is.null(profile) || profile %in% c("", "default")) + return(NULL) + + profile + + } + + renv_bootstrap_path_absolute <- function(path) { + + substr(path, 1L, 1L) %in% c("~", "/", "\\") || ( + substr(path, 1L, 1L) %in% c(letters, LETTERS) && + substr(path, 2L, 3L) %in% c(":/", ":\\") + ) + + } + + renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) { + renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv") + root <- if (renv_bootstrap_path_absolute(renv)) NULL else project + prefix <- if (profile) renv_bootstrap_profile_prefix() + components <- c(root, renv, prefix, ...) + paste(components, collapse = "/") + } + + renv_bootstrap_project_type <- function(path) { + + descpath <- file.path(path, "DESCRIPTION") + if (!file.exists(descpath)) + return("unknown") + + desc <- tryCatch( + read.dcf(descpath, all = TRUE), + error = identity + ) + + if (inherits(desc, "error")) + return("unknown") + + type <- desc$Type + if (!is.null(type)) + return(tolower(type)) + + package <- desc$Package + if (!is.null(package)) + return("package") + + "unknown" + + } + + renv_bootstrap_user_dir <- function() { + dir <- renv_bootstrap_user_dir_impl() + path.expand(chartr("\\", "/", dir)) + } + + renv_bootstrap_user_dir_impl <- function() { + + # use local override if set + override <- getOption("renv.userdir.override") + if (!is.null(override)) + return(override) + + # use R_user_dir if available + tools <- asNamespace("tools") + if (is.function(tools$R_user_dir)) + return(tools$R_user_dir("renv", "cache")) + + # try using our own backfill for older versions of R + envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME") + for (envvar in envvars) { + root <- Sys.getenv(envvar, unset = NA) + if (!is.na(root)) + return(file.path(root, "R/renv")) + } + + # use platform-specific default fallbacks + if (Sys.info()[["sysname"]] == "Windows") + file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv") + else if (Sys.info()[["sysname"]] == "Darwin") + "~/Library/Caches/org.R-project.R/R/renv" + else + "~/.cache/R/renv" + + } + + renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) { + sha <- sha %||% attr(version, "sha", exact = TRUE) + parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L))) + paste(parts, collapse = "") + } + + renv_bootstrap_exec <- function(project, libpath, version) { + if (!renv_bootstrap_load(project, libpath, version)) + renv_bootstrap_run(version, libpath) + } + + renv_bootstrap_run <- function(version, libpath) { + + # perform bootstrap + bootstrap(version, libpath) + + # exit early if we're just testing bootstrap + if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) + return(TRUE) + + # try again to load + if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { + return(renv::load(project = getwd())) + } + + # failed to download or load renv; warn the user + msg <- c( + "Failed to find an renv installation: the project will not be loaded.", + "Use `renv::activate()` to re-initialize the project." + ) + + warning(paste(msg, collapse = "\n"), call. = FALSE) + + } + + renv_json_read <- function(file = NULL, text = NULL) { + + jlerr <- NULL + + # if jsonlite is loaded, use that instead + if ("jsonlite" %in% loadedNamespaces()) { + + json <- catch(renv_json_read_jsonlite(file, text)) + if (!inherits(json, "error")) + return(json) + + jlerr <- json + + } + + # otherwise, fall back to the default JSON reader + json <- catch(renv_json_read_default(file, text)) + if (!inherits(json, "error")) + return(json) + + # report an error + if (!is.null(jlerr)) + stop(jlerr) + else + stop(json) + + } + + renv_json_read_jsonlite <- function(file = NULL, text = NULL) { + text <- paste(text %||% read(file), collapse = "\n") + jsonlite::fromJSON(txt = text, simplifyVector = FALSE) + } + + renv_json_read_default <- function(file = NULL, text = NULL) { + + # find strings in the JSON + text <- paste(text %||% read(file), collapse = "\n") + pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' + locs <- gregexpr(pattern, text, perl = TRUE)[[1]] + + # if any are found, replace them with placeholders + replaced <- text + strings <- character() + replacements <- character() + + if (!identical(c(locs), -1L)) { + + # get the string values + starts <- locs + ends <- locs + attr(locs, "match.length") - 1L + strings <- substring(text, starts, ends) + + # only keep those requiring escaping + strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE) + + # compute replacements + replacements <- sprintf('"\032%i\032"', seq_along(strings)) + + # replace the strings + mapply(function(string, replacement) { + replaced <<- sub(string, replacement, replaced, fixed = TRUE) + }, strings, replacements) + + } + + # transform the JSON into something the R parser understands + transformed <- replaced + transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE) + transformed <- gsub("[[{]", "list(", transformed, perl = TRUE) + transformed <- gsub("[]}]", ")", transformed, perl = TRUE) + transformed <- gsub(":", "=", transformed, fixed = TRUE) + text <- paste(transformed, collapse = "\n") + + # parse it + json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]] + + # construct map between source strings, replaced strings + map <- as.character(parse(text = strings)) + names(map) <- as.character(parse(text = replacements)) + + # convert to list + map <- as.list(map) + + # remap strings in object + remapped <- renv_json_remap(json, map) + + # evaluate + eval(remapped, envir = baseenv()) + + } + + renv_json_remap <- function(json, map) { + + # fix names + if (!is.null(names(json))) { + lhs <- match(names(json), names(map), nomatch = 0L) + rhs <- match(names(map), names(json), nomatch = 0L) + names(json)[rhs] <- map[lhs] + } + + # fix values + if (is.character(json)) + return(map[[json]] %||% json) + + # handle true, false, null + if (is.name(json)) { + text <- as.character(json) + if (text == "true") + return(TRUE) + else if (text == "false") + return(FALSE) + else if (text == "null") + return(NULL) + } + + # recurse + if (is.recursive(json)) { + for (i in seq_along(json)) { + json[i] <- list(renv_json_remap(json[[i]], map)) + } + } + + json + + } + + # load the renv profile, if any + renv_bootstrap_profile_load(project) + + # construct path to library root + root <- renv_bootstrap_library_root(project) + + # construct library prefix for platform + prefix <- renv_bootstrap_platform_prefix() + + # construct full libpath + libpath <- file.path(root, prefix) + + # run bootstrap code + renv_bootstrap_exec(project, libpath, version) + + invisible() + +}) diff --git a/renv/settings.json b/renv/settings.json new file mode 100644 index 0000000..a1ae228 --- /dev/null +++ b/renv/settings.json @@ -0,0 +1,19 @@ +{ + "bioconductor.version": null, + "external.libraries": [], + "ignored.packages": [], + "package.dependency.fields": [ + "Imports", + "Depends", + "LinkingTo" + ], + "ppm.enabled": null, + "ppm.ignored.urls": [], + "r.version": null, + "snapshot.type": "all", + "use.cache": true, + "vcs.ignore.cellar": true, + "vcs.ignore.library": true, + "vcs.ignore.local": true, + "vcs.manage.ignores": true +} diff --git a/tests/testthat.R b/tests/testthat.R new file mode 100644 index 0000000..348f5c1 --- /dev/null +++ b/tests/testthat.R @@ -0,0 +1,12 @@ +# This file is part of the standard setup for testthat. +# It is recommended that you do not modify it. +# +# Where should you do additional test configuration? +# Learn more about the roles of various files in: +# * https://r-pkgs.org/testing-design.html#sec-tests-files-overview +# * https://testthat.r-lib.org/articles/special-files.html + +library(testthat) +library(EFSATools) + +test_check("EFSATools") diff --git a/tests/testthat/test-SCD2.R b/tests/testthat/test-SCD2.R new file mode 100644 index 0000000..47f66a2 --- /dev/null +++ b/tests/testthat/test-SCD2.R @@ -0,0 +1,105 @@ +test_that("The new data must be a data frame", { + expect_error( + SCD2( + newData = 1, + currentData = tibble()) + ) +}) + +test_that("The current data must be a data frame", { + expect_error( + SCD2( + newData = tibble(), + currentData = 1) + ) +}) + +test_that("The key must be a vector", { + expect_error( + SCD2( + newData = tibble(), + currentData = tibble(), + key = 1) + ) +}) + +test_that("A data frame must be returned", { + newData_ <- .activate(dataframe = iris) + currentData_ <- .deactivate(dataframe = newData_) + + checkmate::expect_data_frame( + SCD2(newData = newData_, currentData = currentData_)) +}) + +test_that("The START_DATE column is present", { + newData_ <- .activate(dataframe = iris) + currentData_ <- .deactivate(dataframe = newData_) + + expect_true(any(names(SCD2( + newData = newData_, + currentData = currentData_ + )) == "START_DATE")) +}) + +test_that("The END_DATE column is present", { + newData_ <- .activate(dataframe = iris) + currentData_ <- .deactivate(dataframe = newData_) + + expect_true(any(names(SCD2( + newData = newData_, + currentData = currentData_ + )) == "END_DATE")) +}) + +test_that("The IS_ACTIVE column is present", { + newData_ <- .activate(dataframe = iris) + currentData_ <- .deactivate(dataframe = newData_) + + expect_true(any(names(SCD2( + newData = newData_, + currentData = currentData_ + )) == "IS_ACTIVE")) +}) + +test_that("SCD2 gets activated", { + newData_ <- .activate(dataframe = iris) + currentData_ <- .deactivate(dataframe = newData_) + + mergedData_ <- SCD2(newData = newData_, currentData = currentData_) + + expect_true(all(unique(mergedData_$IS_ACTIVE) %in% c(TRUE, FALSE))) +}) + +test_that("The function must output as expected", { + currentData_ <- tibble::tribble( + ~id, ~colA, ~colB, ~colC, + 1, "a1", "b1", "c1", + 2, "a2", "b2", "c2", + 3, "a3", "b3", "c3" + ) + currentData_ <- .activate(dataframe = currentData_) + + newData_ <- tibble::tribble( + ~id, ~colA, ~colB, ~colC, + 1, "a1", "b1", "c1", # Identical row. + 2, "a2", "b2", "c20", # Almost identical row. + 3, "a4", "b4", "c4" # Different row. + ) + + mergedData_ <- SCD2(newData = newData_, currentData = currentData_) + + expectedResult_ <- tibble::tribble( + ~id, ~colA, ~colB, ~colC, ~IS_ACTIVE, + 1, "a1", "b1", "c1", TRUE, + 2, "a2", "b2", "c20", TRUE, + 3, "a4", "b4", "c4", TRUE, + 2, "a2", "b2", "c2", FALSE, + 3, "a3", "b3", "c3", FALSE) |> + dplyr::arrange(id) + + arrangedMergedData_ <- mergedData_ |> + dplyr::select(-ends_with("DATE")) |> + dplyr::arrange(id) + + expect_equal(arrangedMergedData_, expectedResult_) +}) diff --git a/tests/testthat/test-SSCD2.R b/tests/testthat/test-SSCD2.R new file mode 100644 index 0000000..3a4f61d --- /dev/null +++ b/tests/testthat/test-SSCD2.R @@ -0,0 +1,50 @@ +test_that("The new data must be a data frame", { + expect_error( + SSCD2( + newData = 1, + currentData = tibble()) + ) +}) + +test_that("The current data must be a data frame", { + expect_error( + SSCD2( + newData = tibble(), + currentData = 1) + ) +}) + +test_that("The function must output as expected", { + currentData_ <- tibble::tribble( + ~id, ~colA, ~colB, ~colC, + 1, "a1", "b1", "c1", + 2, "a2", "b2", "c2", + 3, "a3", "b3", "c3" + ) + currentData_ <- .activate(dataframe = currentData_) + + newData_ <- tibble::tribble( + ~id, ~colA, ~colB, ~colC, + 1, "a1", "b1", "c1", # Identical row. + 2, "a2", "b2", "c20", # Almost identical row. + 3, "a4", "b4", "c4" # Different row. + ) + + mergedData_ <- SSCD2(newData = newData_, currentData = currentData_) + + expectedResult_ <- tibble::tribble( + ~id, ~colA, ~colB, ~colC, ~IS_ACTIVE, + 1, "a1", "b1", "c1", FALSE, + 2, "a2", "b2", "c2", FALSE, + 3, "a3", "b3", "c3", FALSE, + 1, "a1", "b1", "c1", TRUE, + 2, "a2", "b2", "c20", TRUE, + 3, "a4", "b4", "c4", TRUE) |> + dplyr::arrange(id) + + arrangedMergedData_ <- mergedData_ |> + dplyr::select(-ends_with("DATE")) |> + dplyr::arrange(id) + + expect_equal(expectedResult_, arrangedMergedData_) +}) diff --git a/tests/testthat/test-activate.R b/tests/testthat/test-activate.R new file mode 100644 index 0000000..3c2a17d --- /dev/null +++ b/tests/testthat/test-activate.R @@ -0,0 +1,34 @@ +test_that("The parameter must be a data frame", { + expect_error( + .activate(dataframe = 1) + ) +}) + +test_that("Iris gets activated", { + checkmate::expect_data_frame( + .activate(dataframe = iris)) +}) + +test_that("The START_DATE column is present", { + dataframe_ <- .activate(dataframe = iris) + expect_true( + any(names(dataframe_) == "START_DATE")) + expect_true( + all(!is.null(dataframe_$START_DATE))) +}) + +test_that("The END_DATE column is present", { + dataframe_ <- .activate(dataframe = iris) + expect_true( + any(names(dataframe_) == "END_DATE")) + expect_true( + all(is.na(dataframe_$END_DATE))) +}) + +test_that("The IS_ACTIVE column is present", { + dataframe_ <- .activate(dataframe = iris) + expect_true( + any(names(dataframe_) == "IS_ACTIVE")) + expect_true( + all(dataframe_$IS_ACTIVE == TRUE)) +}) diff --git a/tests/testthat/test-deactivate.R b/tests/testthat/test-deactivate.R new file mode 100644 index 0000000..e6f138e --- /dev/null +++ b/tests/testthat/test-deactivate.R @@ -0,0 +1,32 @@ +test_that("The parameter must be a data frame", { + expect_error( + .deactivate(dataframe = 1) + ) +}) + +test_that("Iris gets deactivated", { + dataframe_ <- .activate(dataframe = iris) + + checkmate::expect_data_frame( + .deactivate(dataframe = dataframe_)) +}) + +test_that("The END_DATE column is present", { + dataframe_ <- .activate(dataframe = iris) + dataframe_ <- .deactivate(dataframe = dataframe_) + + expect_true( + any(names(.deactivate(dataframe = dataframe_)) == "END_DATE")) + expect_true( + all(!is.null(dataframe_["END_DATE"]))) +}) + +test_that("The IS_ACTIVE column is present", { + dataframe_ <- .activate(dataframe = iris) + dataframe_ <- .deactivate(dataframe = dataframe_) + + expect_true( + any(names(.deactivate(dataframe = dataframe_)) == "IS_ACTIVE")) + expect_true( + all(dataframe_$IS_ACTIVE == FALSE)) +}) diff --git a/tests/testthat/test-dropEmpty.R b/tests/testthat/test-dropEmpty.R new file mode 100644 index 0000000..be1efad --- /dev/null +++ b/tests/testthat/test-dropEmpty.R @@ -0,0 +1,42 @@ +test_that("The parameter must be a data frame", { + expect_error( + dropEmpty(dataframe = 1) + ) +}) + +test_that("A dataframe must be returned", { + dataframe_ <- head(iris, 10) + + # The Species column is going to be dropped. + dataframe_$Species <- NA + dataframeWithoutSpecies_ <- dropEmpty(dataframe = dataframe_) + + # The first row is going to be dropped. + dataframe_[1, ] <- NA + dataframeWithoutFirstRow_ <- dropEmpty(dataframe = dataframe_) + + expect_true(is.data.frame(dataframeWithoutSpecies_)) + expect_true(is.data.frame(dataframeWithoutFirstRow_)) +}) + +test_that("Drops a column", { + dataframe_ <- head(iris, 10) + + # The Species column is going to be dropped. + dataframe_$Species <- NA + dataframeWithoutSpecies_ <- dropEmpty(dataframe_) + numberOfColumns_ <- ncol(dataframeWithoutSpecies_) + + expect_equal(numberOfColumns_, 4) +}) + +test_that("Drops a row", { + dataframe_ <- head(iris, 10) + + # The first row is going to be dropped. + dataframe_[1, ] <- NA + dataframeWithoutFirstRow_ <- dropEmpty(dataframe = dataframe_) + numberOfRows_ <- nrow(dataframeWithoutFirstRow_) + + expect_equal(numberOfRows_, 9) +}) diff --git a/tests/testthat/test-enrich.R b/tests/testthat/test-enrich.R new file mode 100644 index 0000000..fd29e31 --- /dev/null +++ b/tests/testthat/test-enrich.R @@ -0,0 +1,67 @@ +test_that("The data frame to enrich must be a data frame", { + expect_error( + enrich( + dataframe = 1, + catalogue = tibble(), + joinBy = "", + enrichedColumnName = "") + ) +}) + +test_that("The catalogue must be a data frame", { + expect_error( + enrich( + dataframe = tibble(), + catalogue = 1, + joinBy = "", + enrichedColumnName = "") + ) +}) + +test_that("The catalogue must contain the NAME and CODE columns", { + expect_error( + enrich( + dataframe = tibble(), + catalogue = tibble(), + joinBy = "", + enrichedColumnName = "") + ) +}) + +test_that("The join key must be a string", { + expect_error( + enrich( + dataframe = tibble(), + catalogue = tibble(), + joinBy = 1, + enrichedColumnName = "") + ) +}) + +test_that("The enriched column name must be a string", { + expect_error( + enrich( + dataframe = tibble(), + catalogue = tibble(), + joinBy = "", + enrichedColumnName = 1) + ) +}) + +test_that("A data frame must be returned", { + dataframe_ <- iris |> dplyr::rename(CODE = Species) + + catalogue_ <- iris |> + dplyr::rename(CODE = Species) |> + dplyr::mutate(NAME = "test") |> + dplyr::select(CODE, NAME) |> + unique() + + enriched_ <- enrich( + dataframe = dataframe_, + catalogue = catalogue_, + joinBy = "CODE", + enrichedColumnName = "enrichedColumn") + + expect_true(is.data.frame(enriched_)) +}) diff --git a/tests/testthat/test-removeReplicatedColumns.R b/tests/testthat/test-removeReplicatedColumns.R new file mode 100644 index 0000000..a1669fe --- /dev/null +++ b/tests/testthat/test-removeReplicatedColumns.R @@ -0,0 +1,45 @@ +test_that("The data frame to manipulate must be a data frame", { + expect_error( + removeReplicatedColumns( + dataframe = 1, + prefix = "") + ) +}) + +test_that("The prefix must be a string", { + expect_error( + removeReplicatedColumns( + dataframe = tibble(), + prefix = 1) + ) +}) + +test_that("A data frame must be returned", { + dataframe_ <- data.frame( + prefix_1 = c(1, NA, NA), + prefix_2 = c(NA, 2, NA), + prefix_3 = c(NA, NA, 3), + another_col = c(NA, NA, 3)) + + dataframeDeduplicated_ <- suppressWarnings( + removeReplicatedColumns( + dataframe = dataframe_, + prefix = "prefix")) + + expect_true(is.data.frame(dataframeDeduplicated_)) +}) + +test_that("Only the deduplicated column gets returned", { + dataframe_ <- data.frame( + prefix_1 = c(1, NA, NA), + prefix_2 = c(NA, 2, NA), + prefix_3 = c(NA, NA, 3), + another_col = c(NA, NA, 3)) + + dataframeDeduplicated_ <- suppressWarnings( + removeReplicatedColumns( + dataframe = dataframe_, + prefix = "prefix")) + + expect_equal(ncol(dataframeDeduplicated_), 2) +}) diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 0000000..097b241 --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1,2 @@ +*.html +*.R diff --git a/vignettes/EFSATools.Rmd b/vignettes/EFSATools.Rmd new file mode 100644 index 0000000..6726dac --- /dev/null +++ b/vignettes/EFSATools.Rmd @@ -0,0 +1,134 @@ +--- +title: "EFSATools" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{EFSATools} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include=FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +## Overview + +The **EFSATools** package brings together all the functions developed for EFSA's ad hoc data collections, providing tools for dataset operations as well as utilities designed to preserve data history. + +The package is intended for researchers, analysts, and practitioners who require convenient programmatic access to data collection utilities. + +## Installation + +### From CRAN + +```{r eval=FALSE} +install.packages("EFSATools") +``` + +### Development version (from GitHub) + +To install the latest development version: + +```{r eval=FALSE} +# install.packages("devtools") +devtools::install_github("openefsa/EFSATools") +``` + +## Basic usage + +The main purpose of *EFSATools* is to provide tools for managing datasets and tracking data history within the context of data collections. + +Below are examples demonstrating how to use the functions in this package. First, load the *EFSATools* package: + +```{r loadLibrary, eval=FALSE} +library(EFSATools) +``` + +To explore the arguments and usage of a specific function, you can run: + +```{r eval=FALSE} +help("") +``` + +This will show the full documentation for the function, including its arguments, return values, and usage examples. + +For example, if you are working with the `SCD2()` function, you can check its documentation with: + +```{r eval=FALSE} +help("SCD2") +``` + +## Dropping empty rows and columns from a data frame + +If a data frame contain empty rows or columns, you can remove them using the `dropEmpty()` function, as follows: + +```{r dropEmpty, eval=FALSE} +irisDropped <- dropEmpty(dataframe = iris) + +print(head(irisDropped)) +``` + +## Enriching a data frame with an EFSA's catalogue + +The `enrich()` function enables the augmentation of a data frame using information stored in an EFSA's catalogue. It requires specifying the column used to join the two datasets, as well as the name of the column that will contain the enriched information (namely, the 'NAME' field of EFSA's catalogues). + +```{r enrich, eval=FALSE} +enrichedDataFrame <- enrich( + dataframe = dataframe_, + catalogue = CV_MTX_, + joinBy = "CODE", + enrichedColumnName = "enrichedColumn" +) + +print(head(enrichedDataFrame)) +``` + +## Removing replicated columns from a data frame + +The `removeReplicatedColumns()` function merges all the replicated columns in a data frame into a single column whose name includes the "_deduplicated" suffix. After the merge, the original replicated columns are removed from the data frame. + +In the following example, we present a data frame containing the columns *region_1*, *region_2*, ..., *region_n* with *n* > 100. Using the `removeReplicatedColumns()` function, these columns can be efficiently consolidated into a single *region_deduplicated* column, assuming that for each row only one of the *n* columns contains a meaningful (non-NA) value. + +```{r removeReplicatedColumns, eval=FALSE} +iris$Species_1 <- iris$Species +iris$Species_2 <- iris$Species +iris$Species <- NULL + +irisDeduplicated <- removeReplicatedColumns( + dataframe = iris, + prefix = "Species_" +) + +print(head(irisDeduplicated)) +``` + +## Implementing a "Simple" Slowly Changing Dimension Type 2 (SSCD2) + +The `SSCD2()` function makes it possible to preserve data history when new data becomes available by implementing a simplified version of Slowly Changing Dimension Type 2. It marks all records in the current data frame as inactive and appends the new data, flagging each newly added record as active. + +Unlike the `SCD2()` function, `SSCD2()` does not check which records have actually changed. Instead, it marks all existing records as inactive and treats all incoming records as new, setting the previous ones to inactive status even if they are still included in the updated dataset. + +An example of how to use the function is provided below: + +```{r SSCD2, eval=FALSE} +sscd2Dataframe <- SSCD2(newData = newDataframe, currentData = oldDataframe) + +print(head(sscd2Dataframe)) +``` + +## Implementing a Slowly Changing Dimension Type 2 (SCD2) + +The `SCD2()` function makes it possible to preserve data history when new data becomes available by implementing a Slowly Changing Dimension Type 2. It compares the current records with the new ones, marking as inactive any existing records that no longer appear in the updated dataset. Then, it flags as active any new records that are not present among the currently active data. + +Unlike the `SSCD2()` function, `SCD2()` checks which records have actually changed. It marks as inactive any existing records that no longer appear in the updated dataset, and flags as active any new records that are not present among the currently active data. + +An example of how to use the function is provided below: + +```{r SCD2, eval=FALSE} +scd2Dataframe <- SCD2(newData = newDataframe, currentData = oldDataframe) + +print(head(scd2Dataframe)) +``` From e7029063ba531bb42a0e0e1e2ecf10419697580d Mon Sep 17 00:00:00 2001 From: Lorenzo Copelli Date: Tue, 7 Apr 2026 10:12:35 +0200 Subject: [PATCH 2/3] Improved codecov.yml. (#2) --- .github/workflows/codecov.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 6674536..5167b7c 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -18,10 +18,9 @@ jobs: use-public-rspm: true - name: Install R dependencies - uses: r-lib/actions/setup-r-dependencies@v2 - with: - extra-packages: any::covr, any::devtools, local::. - needs: coverage + run: | + Rscript -e "install.packages(c('covr', 'devtools'))" + Rscript -e "devtools::install_deps(dependencies = TRUE)" - name: Run tests and upload coverage to Codecov env: From 88c2a46f08d354098d6f49dbc38a9615c2c56949 Mon Sep 17 00:00:00 2001 From: Lorenzo Copelli Date: Tue, 7 Apr 2026 10:28:15 +0200 Subject: [PATCH 3/3] Fixed codecov.yml. (#3) --- .github/workflows/codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 5167b7c..aa14e64 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -19,7 +19,7 @@ jobs: - name: Install R dependencies run: | - Rscript -e "install.packages(c('covr', 'devtools'))" + Rscript -e "install.packages(c('covr', 'devtools', 'remotes'))" Rscript -e "devtools::install_deps(dependencies = TRUE)" - name: Run tests and upload coverage to Codecov