diff --git a/.Rbuildignore b/.Rbuildignore index 88b0533..b6d0c82 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,3 +1,5 @@ +^renv$ +^renv\.lock$ ^LICENSE\.md$ ^.*\.Rproj$ ^\.Rproj\.user$ @@ -6,3 +8,5 @@ ^docs$ ^pkgdown$ ^\.lintr$ +^renv*$ +^data-raw$ diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 6388f75..c436cb6 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -25,5 +25,5 @@ jobs: extra-packages: lintr - name: Lint - run: lintr::lint_package() + run: lintr::lint_package(linters = lintr::linters_with_defaults(object_name_linter = lintr::object_name_linter("camelCase"))) shell: Rscript {0} diff --git a/.gitignore b/.gitignore index 0dddc4b..6f89102 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,7 @@ vignettes/*.pdf .Renviron inst/doc docs + +# Local libraries +.Rprofile +renv/ diff --git a/.lintr b/.lintr index be9b6d4..e6308d4 100644 --- a/.lintr +++ b/.lintr @@ -1,4 +1,4 @@ -linters: with_defaults( +linters: linters_with_defaults( object_name_linter = object_name_linter(styles = "camelCase"), line_length_linter(80), T_and_F_symbol_linter diff --git a/DESCRIPTION b/DESCRIPTION index e2161da..12a68b4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: DevelExample Title: A Basic R Package to Demonstrate a Cycle of Code Development -Version: 0.0.1 +Version: 0.1.0 Authors@R: person(given = "Joshua", family = "Campbell", @@ -15,10 +15,12 @@ Encoding: UTF-8 biocViews: Clustering LazyData: false Roxygen: list(markdown = TRUE) -RoxygenNote: 7.1.1 +RoxygenNote: 7.2.1 Suggests: knitr, rmarkdown, - testthat (>= 3.0.0) + testthat, Config/testthat/edition: 3 VignetteBuilder: knitr +Depends: + R (>= 2.10) diff --git a/NAMESPACE b/NAMESPACE index 01843dc..6bd620a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,3 +1,4 @@ # Generated by roxygen2: do not edit by hand +export(euclideanDist) export(hello) diff --git a/NEWS.md b/NEWS.md index 4cd8ae2..0edaaa4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ -# Changes in Version 0.0.1 (2022-05-08) -* Created package -* Added Hello World function -* Added documentation, unit tests, and vignettes +# Changes in Version 0.1.0 (2022-05-20) +* Added function to calculate euclidean distance + +# DevelExample 0.1.0 + * Added a `NEWS.md` file to track changes to the package. diff --git a/R/data.R b/R/data.R new file mode 100644 index 0000000..8c6e0e6 --- /dev/null +++ b/R/data.R @@ -0,0 +1,11 @@ +#' Example dataset +#' +#' A dataset containing a matrix with two columns that were generated +#' with a random normal distribution with a mean of 0 and stdev of 1. +#' +#' @format A matrix with 100 rows and 2 columns +#' @keywords datasets +#' @usage data("exampleData") +#' @examples +#' data("exampleData") +"exampleData" diff --git a/R/distance.R b/R/distance.R new file mode 100644 index 0000000..19aef9e --- /dev/null +++ b/R/distance.R @@ -0,0 +1,32 @@ +#' @title Euclidean distance +#' @description Calculates Euclidean distance between two vectors. An error will +#' be given if NAs are present in either vector. +#' +#' @param a The first vector to use in the distance calculation. +#' @param b The second vector to use in the distance calculation. +#' @param verbose Boolean. If \code{TRUE}, a message will be printed. +#' Default \code{TRUE}. +#' @return A numeric value of a distance +#' @examples +#' data(exampleData) +#' euclideanDist(exampleData[, 1], exampleData[, 2], verbose = FALSE) +#' @export +euclideanDist <- function(a, b, verbose = FALSE) { + if (isTRUE(verbose)) { + message("Calculating distance ...") + } + + # Check validity of data + .checkData(a) + .checkData(b) + + # Perform calculation + res <- sqrt(sum((a - b)^2)) + return(res) +} + +.checkData <- function(input) { + if (any(is.na(input))) { + stop("'input' must not contain NAs") + } +} diff --git a/_pkgdown.yml b/_pkgdown.yml index e69de29..d71acfb 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -0,0 +1,4 @@ +url: ~ +template: + bootstrap: 5 + diff --git a/data-raw/exampleData.R b/data-raw/exampleData.R new file mode 100644 index 0000000..9f83dff --- /dev/null +++ b/data-raw/exampleData.R @@ -0,0 +1,6 @@ +## code to prepare `exampleData` dataset goes here +set.seed(123) +a <- rnorm(100) +b <- rnorm(100) +exampleData <- cbind(a, b) +usethis::use_data(exampleData, overwrite = TRUE) diff --git a/data/exampleData.rda b/data/exampleData.rda new file mode 100644 index 0000000..d09d507 Binary files /dev/null and b/data/exampleData.rda differ diff --git a/man/euclideanDist.Rd b/man/euclideanDist.Rd new file mode 100644 index 0000000..00aa127 --- /dev/null +++ b/man/euclideanDist.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/distance.R +\name{euclideanDist} +\alias{euclideanDist} +\title{Euclidean distance} +\usage{ +euclideanDist(a, b, verbose = FALSE) +} +\arguments{ +\item{a}{The first vector to use in the distance calculation.} + +\item{b}{The second vector to use in the distance calculation.} + +\item{verbose}{Boolean. If \code{TRUE}, a message will be printed. +Default \code{TRUE}.} +} +\value{ +A numeric value of a distance +} +\description{ +Calculates Euclidean distance between two vectors. An error will +be given if NAs are present in either vector. +} +\examples{ +data(exampleData) +euclideanDist(exampleData[, 1], exampleData[, 2], verbose = FALSE) +} diff --git a/man/exampleData.Rd b/man/exampleData.Rd new file mode 100644 index 0000000..cf7cdbd --- /dev/null +++ b/man/exampleData.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{exampleData} +\alias{exampleData} +\title{Example dataset} +\format{ +A matrix with 100 rows and 2 columns +} +\usage{ +data("exampleData") +} +\description{ +A dataset containing a matrix with two columns that were generated +with a random normal distribution with a mean of 0 and stdev of 1. +} +\examples{ +data("exampleData") +} +\keyword{datasets} diff --git a/renv.lock b/renv.lock new file mode 100644 index 0000000..fb1332b --- /dev/null +++ b/renv.lock @@ -0,0 +1,553 @@ +{ + "R": { + "Version": "4.2.1", + "Repositories": [ + { + "Name": "BioCsoft", + "URL": "https://bioconductor.org/packages/3.15/bioc" + }, + { + "Name": "BioCann", + "URL": "https://bioconductor.org/packages/3.15/data/annotation" + }, + { + "Name": "BioCexp", + "URL": "https://bioconductor.org/packages/3.15/data/experiment" + }, + { + "Name": "BioCworkflows", + "URL": "https://bioconductor.org/packages/3.15/workflows" + }, + { + "Name": "BioCbooks", + "URL": "https://bioconductor.org/packages/3.15/books" + }, + { + "Name": "CRAN", + "URL": "https://cran.rstudio.com" + } + ] + }, + "Packages": { + "R6": { + "Package": "R6", + "Version": "2.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "470851b6d5d0ac559e9d01bb352b4021", + "Requirements": [] + }, + "base64enc": { + "Package": "base64enc", + "Version": "0.1-3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "543776ae6848fde2f48ff3816d0628bc", + "Requirements": [] + }, + "brio": { + "Package": "brio", + "Version": "1.1.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "976cf154dfb043c012d87cddd8bca363", + "Requirements": [] + }, + "bslib": { + "Package": "bslib", + "Version": "0.4.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "be5ee090716ce1671be6cd5d7c34d091", + "Requirements": [ + "cachem", + "htmltools", + "jquerylib", + "jsonlite", + "memoise", + "rlang", + "sass" + ] + }, + "cachem": { + "Package": "cachem", + "Version": "1.0.6", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "648c5b3d71e6a37e3043617489a0a0e9", + "Requirements": [ + "fastmap", + "rlang" + ] + }, + "callr": { + "Package": "callr", + "Version": "3.7.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "358689cac9fe93b1bb3a19088d2dbed8", + "Requirements": [ + "R6", + "processx" + ] + }, + "cli": { + "Package": "cli", + "Version": "3.4.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "0d297d01734d2bcea40197bd4971a764", + "Requirements": [] + }, + "crayon": { + "Package": "crayon", + "Version": "1.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "8dc45fd8a1ee067a92b85ef274e66d6a", + "Requirements": [] + }, + "desc": { + "Package": "desc", + "Version": "1.4.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "6b9602c7ebbe87101a9c8edb6e8b6d21", + "Requirements": [ + "R6", + "cli", + "rprojroot" + ] + }, + "diffobj": { + "Package": "diffobj", + "Version": "0.3.5", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "bcaa8b95f8d7d01a5dedfd959ce88ab8", + "Requirements": [ + "crayon" + ] + }, + "digest": { + "Package": "digest", + "Version": "0.6.29", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "cf6b206a045a684728c3267ef7596190", + "Requirements": [] + }, + "ellipsis": { + "Package": "ellipsis", + "Version": "0.3.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "bb0eec2fe32e88d9e2836c2f73ea2077", + "Requirements": [ + "rlang" + ] + }, + "evaluate": { + "Package": "evaluate", + "Version": "0.16", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "9a3d3c345f8a5648abe61608aaa29518", + "Requirements": [] + }, + "fansi": { + "Package": "fansi", + "Version": "1.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "83a8afdbe71839506baa9f90eebad7ec", + "Requirements": [] + }, + "fastmap": { + "Package": "fastmap", + "Version": "1.1.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "77bd60a6157420d4ffa93b27cf6a58b8", + "Requirements": [] + }, + "fs": { + "Package": "fs", + "Version": "1.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "7c89603d81793f0d5486d91ab1fc6f1d", + "Requirements": [] + }, + "glue": { + "Package": "glue", + "Version": "1.6.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "4f2596dfb05dac67b9dc558e5c6fba2e", + "Requirements": [] + }, + "highr": { + "Package": "highr", + "Version": "0.9", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "8eb36c8125038e648e5d111c0d7b2ed4", + "Requirements": [ + "xfun" + ] + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "6496090a9e00f8354b811d1a2d47b566", + "Requirements": [ + "base64enc", + "digest", + "fastmap", + "rlang" + ] + }, + "jquerylib": { + "Package": "jquerylib", + "Version": "0.1.4", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "5aab57a3bd297eee1c1d862735972182", + "Requirements": [ + "htmltools" + ] + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "1.8.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "d07e729b27b372429d42d24d503613a0", + "Requirements": [] + }, + "knitr": { + "Package": "knitr", + "Version": "1.40", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "caea8b0f899a0b1738444b9bc47067e7", + "Requirements": [ + "evaluate", + "highr", + "stringr", + "xfun", + "yaml" + ] + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "25f74670fa7d3277fe3ad8c1712a699f", + "Requirements": [ + "glue", + "rlang" + ] + }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "7ce2733a9826b3aeb1775d56fd305472", + "Requirements": [] + }, + "memoise": { + "Package": "memoise", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c", + "Requirements": [ + "cachem", + "rlang" + ] + }, + "pillar": { + "Package": "pillar", + "Version": "1.8.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "f2316df30902c81729ae9de95ad5a608", + "Requirements": [ + "cli", + "fansi", + "glue", + "lifecycle", + "rlang", + "utf8", + "vctrs" + ] + }, + "pkgconfig": { + "Package": "pkgconfig", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "01f28d4278f15c76cddbea05899c5d6f", + "Requirements": [] + }, + "pkgload": { + "Package": "pkgload", + "Version": "1.3.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "4b20f937a363c78a5730265c1925f54a", + "Requirements": [ + "cli", + "crayon", + "desc", + "fs", + "glue", + "rlang", + "rprojroot", + "withr" + ] + }, + "praise": { + "Package": "praise", + "Version": "1.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a555924add98c99d2f411e37e7d25e9f", + "Requirements": [] + }, + "processx": { + "Package": "processx", + "Version": "3.7.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "f91df0f5f31ffdf88bc0b624f5ebab0f", + "Requirements": [ + "R6", + "ps" + ] + }, + "ps": { + "Package": "ps", + "Version": "1.7.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "8b93531308c01ad0e56d9eadcc0c4fcd", + "Requirements": [] + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "5e3c5dc0b071b21fa128676560dbe94d", + "Requirements": [] + }, + "rematch2": { + "Package": "rematch2", + "Version": "2.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "76c9e04c712a05848ae7a23d2f170a40", + "Requirements": [ + "tibble" + ] + }, + "renv": { + "Package": "renv", + "Version": "0.15.5", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "6a38294e7d12f5d8e656b08c5bd8ae34", + "Requirements": [] + }, + "rlang": { + "Package": "rlang", + "Version": "1.0.6", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "4ed1f8336c8d52c3e750adcdc57228a7", + "Requirements": [] + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.16", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "0f3eaa1547e2c6880d4de1c043ac6826", + "Requirements": [ + "bslib", + "evaluate", + "htmltools", + "jquerylib", + "jsonlite", + "knitr", + "stringr", + "tinytex", + "xfun", + "yaml" + ] + }, + "rprojroot": { + "Package": "rprojroot", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "1de7ab598047a87bba48434ba35d497d", + "Requirements": [] + }, + "sass": { + "Package": "sass", + "Version": "0.4.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "1b191143d7d3444d504277843f3a95fe", + "Requirements": [ + "R6", + "fs", + "htmltools", + "rappdirs", + "rlang" + ] + }, + "stringi": { + "Package": "stringi", + "Version": "1.7.8", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a68b980681bcbc84c7a67003fa796bfb", + "Requirements": [] + }, + "stringr": { + "Package": "stringr", + "Version": "1.4.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a66ad12140cd34d4f9dfcc19e84fc2a5", + "Requirements": [ + "glue", + "magrittr", + "stringi" + ] + }, + "testthat": { + "Package": "testthat", + "Version": "3.1.4", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "f76c2a02d0fdc24aa7a47ea34261a6e3", + "Requirements": [ + "R6", + "brio", + "callr", + "cli", + "crayon", + "desc", + "digest", + "ellipsis", + "evaluate", + "jsonlite", + "lifecycle", + "magrittr", + "pkgload", + "praise", + "processx", + "ps", + "rlang", + "waldo", + "withr" + ] + }, + "tibble": { + "Package": "tibble", + "Version": "3.1.8", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "56b6934ef0f8c68225949a8672fe1a8f", + "Requirements": [ + "fansi", + "lifecycle", + "magrittr", + "pillar", + "pkgconfig", + "rlang", + "vctrs" + ] + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.41", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "6edfe5df6431a724b4254c0591e34ab3", + "Requirements": [ + "xfun" + ] + }, + "utf8": { + "Package": "utf8", + "Version": "1.2.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "c9c462b759a5cc844ae25b5942654d13", + "Requirements": [] + }, + "vctrs": { + "Package": "vctrs", + "Version": "0.4.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "8b54f22e2a58c4f275479c92ce041a57", + "Requirements": [ + "cli", + "glue", + "rlang" + ] + }, + "waldo": { + "Package": "waldo", + "Version": "0.4.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "035fba89d0c86e2113120f93301b98ad", + "Requirements": [ + "cli", + "diffobj", + "fansi", + "glue", + "rematch2", + "rlang", + "tibble" + ] + }, + "withr": { + "Package": "withr", + "Version": "2.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "c0e49a9760983e81e55cdd9be92e7182", + "Requirements": [] + }, + "xfun": { + "Package": "xfun", + "Version": "0.33", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "1a666f915cd65072f4ccf5b2888d5d39", + "Requirements": [] + }, + "yaml": { + "Package": "yaml", + "Version": "2.3.5", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "458bb38374d73bf83b1bb85e353da200", + "Requirements": [] + } + } +} diff --git a/tests/testthat.R b/tests/testthat.R index 35ab969..94ef759 100644 --- a/tests/testthat.R +++ b/tests/testthat.R @@ -1,3 +1,11 @@ +# 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/tests.html +# * https://testthat.r-lib.org/reference/test_package.html#special-files + library(testthat) library(DevelExample) diff --git a/tests/testthat/test-euclidean.R b/tests/testthat/test-euclidean.R new file mode 100644 index 0000000..99068e5 --- /dev/null +++ b/tests/testthat/test-euclidean.R @@ -0,0 +1,9 @@ +library("DevelExample") +data(exampleData) + +test_that("Testing euclideanDist function", { + res <- dist(rbind(exampleData[, 1], exampleData[, 2]))[1] + expect_equal(euclideanDist(exampleData[, 1], exampleData[, 2]), res) + + expect_error(euclideanDist(c(1, 2), c(NA, 2)), regexp = "contain NAs") +}) diff --git a/vignettes/DevelExample.Rmd b/vignettes/DevelExample.Rmd index 170fadb..508bfc5 100644 --- a/vignettes/DevelExample.Rmd +++ b/vignettes/DevelExample.Rmd @@ -40,3 +40,15 @@ It is usually a good idea to show the session information to help with reproduci sessionInfo() ``` +To calculate the euclidean distance between two vectors, we can use the `euclideanDist` function. In this example we will generate two random vectors from normal distributions with two different means and calculate the distance between them: + +```{r dist} +set.seed(12345) +v1 <- rnorm(10000, mean = 1) +v2 <- rnorm(10000, mean = 2) +res <- euclideanDist(v1, v2, verbose = FALSE) +res +``` + +The `set.seed` function is used for the random number generator and ensures the same vectors will be produced each time for reproducibility. +