From 3e63982968c39df44f910534e8ed7bdf0e8df411 Mon Sep 17 00:00:00 2001 From: Emil Hvitfeldt Date: Tue, 7 May 2024 16:53:53 -0700 Subject: [PATCH 1/2] make user facing function not start with new --- NAMESPACE | 2 +- R/altrep.R | 16 ++- ...{new_sparse_double.Rd => sparse_double.Rd} | 19 ++- tests/testthat/_snaps/altrep.md | 114 +++++++++--------- tests/testthat/test-altrep.R | 88 +++++++------- tests/testthat/test-extractors.R | 8 +- 6 files changed, 134 insertions(+), 113 deletions(-) rename man/{new_sparse_double.Rd => sparse_double.Rd} (59%) diff --git a/NAMESPACE b/NAMESPACE index 66884da..4ede74c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,5 @@ # Generated by roxygen2: do not edit by hand -export(new_sparse_double) +export(sparse_double) import(rlang) useDynLib(sparsevctrs, .registration = TRUE) diff --git a/R/altrep.R b/R/altrep.R index da5e7b7..bf288c7 100644 --- a/R/altrep.R +++ b/R/altrep.R @@ -1,4 +1,4 @@ -#' Create sparse numeric vector +#' Create sparse double vector #' #' @param value Numeric vector, values of non-zero entries. #' @param position integer vector, indices of non-zero entries. @@ -11,8 +11,16 @@ #' setting `options("sparsevctrs.verbose_materialize" = TRUE)` will print a #' message each time a sparse vector has been forced to materialize. #' +#' @examples +#' sparse_double(numeric(), integer(), 10) +#' +#' sparse_double(c(pi, 5, 0.1), c(2, 5, 10), 10) +#' +#' str( +#' sparse_double(c(pi, 5, 0.1), c(2, 5, 10), 1000000000) +#' ) #' @export -new_sparse_double <- function(value, position, length) { +sparse_double <- function(value, position, length) { check_number_whole(length, min = 0) if (!is.integer(length)) { length <- as.integer(length) @@ -127,6 +135,10 @@ new_sparse_double <- function(value, position, length) { ) } + new_sparse_double(value, position, length) +} + +new_sparse_double <- function(value, position, length) { x <- list( val = value, pos = position, diff --git a/man/new_sparse_double.Rd b/man/sparse_double.Rd similarity index 59% rename from man/new_sparse_double.Rd rename to man/sparse_double.Rd index eab8cc3..919b7aa 100644 --- a/man/new_sparse_double.Rd +++ b/man/sparse_double.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/altrep.R -\name{new_sparse_double} -\alias{new_sparse_double} -\title{Create sparse numeric vector} +\name{sparse_double} +\alias{sparse_double} +\title{Create sparse double vector} \usage{ -new_sparse_double(value, position, length) +sparse_double(value, position, length) } \arguments{ \item{value}{Numeric vector, values of non-zero entries.} @@ -14,7 +14,7 @@ new_sparse_double(value, position, length) \item{length}{Integer, Length of vector.} } \description{ -Create sparse numeric vector +Create sparse double vector } \details{ For developers: @@ -22,3 +22,12 @@ For developers: setting \code{options("sparsevctrs.verbose_materialize" = TRUE)} will print a message each time a sparse vector has been forced to materialize. } +\examples{ +sparse_double(numeric(), integer(), 10) + +sparse_double(c(pi, 5, 0.1), c(2, 5, 10), 10) + +str( + sparse_double(c(pi, 5, 0.1), c(2, 5, 10), 1000000000) +) +} diff --git a/tests/testthat/_snaps/altrep.md b/tests/testthat/_snaps/altrep.md index a614ada..1a22493 100644 --- a/tests/testthat/_snaps/altrep.md +++ b/tests/testthat/_snaps/altrep.md @@ -1,40 +1,40 @@ # input checking is done correctly Code - new_sparse_double("1", 1, 1) + sparse_double("1", 1, 1) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `value` must be a numeric vector, not a string. --- Code - new_sparse_double(NULL, 1, 1) + sparse_double(NULL, 1, 1) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `value` must be a numeric vector, not NULL. --- Code - new_sparse_double(NA, 1, 1) + sparse_double(NA, 1, 1) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `value` must be a numeric vector, not `NA`. --- Code - new_sparse_double(Inf, 1, 1) + sparse_double(Inf, 1, 1) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: x `value` must not contain infinite values. i Infinite values at index: 1. --- Code - new_sparse_double(NaN, 1, 1) + sparse_double(NaN, 1, 1) Condition Error in `if (any(value == 0)) ...`: ! missing value where TRUE/FALSE needed @@ -42,49 +42,49 @@ --- Code - new_sparse_double(1, 1.5, 1) + sparse_double(1, 1.5, 1) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: x `position` must contain integer values. i Non-integer values at index: 1. --- Code - new_sparse_double(1, "1", 1) + sparse_double(1, "1", 1) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `position` must be a integer vector, not a number. --- Code - new_sparse_double(1, NULL, 1) + sparse_double(1, NULL, 1) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `position` must be a integer vector, not a number. --- Code - new_sparse_double(1, NA, 1) + sparse_double(1, NA, 1) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `position` must be a integer vector, not a number. --- Code - new_sparse_double(1, Inf, 1) + sparse_double(1, Inf, 1) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: x `position` must not contain infinite values. i Infinite values at index: 1. --- Code - new_sparse_double(1, NaN, 1) + sparse_double(1, NaN, 1) Condition Error in `if (len_position > 0 && max(position) > length) ...`: ! missing value where TRUE/FALSE needed @@ -92,159 +92,159 @@ --- Code - new_sparse_double(numeric(0), integer(0), c(1, 10)) + sparse_double(numeric(0), integer(0), c(1, 10)) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `length` must be a whole number, not a double vector. --- Code - new_sparse_double(numeric(0), integer(0), 1.5) + sparse_double(numeric(0), integer(0), 1.5) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `length` must be a whole number, not the number 1.5. --- Code - new_sparse_double(numeric(0), integer(0), "1") + sparse_double(numeric(0), integer(0), "1") Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `length` must be a whole number, not the string "1". --- Code - new_sparse_double(numeric(0), integer(0), NA) + sparse_double(numeric(0), integer(0), NA) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `length` must be a whole number, not `NA`. --- Code - new_sparse_double(numeric(0), integer(0), Inf) + sparse_double(numeric(0), integer(0), Inf) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `length` must be a whole number, not `Inf`. --- Code - new_sparse_double(numeric(0), integer(0), NULL) + sparse_double(numeric(0), integer(0), NULL) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `length` must be a whole number, not `NULL`. --- Code - new_sparse_double(numeric(0), integer(0), NaN) + sparse_double(numeric(0), integer(0), NaN) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `length` must be a whole number, not `NaN`. --- Code - new_sparse_double(1:4, 1:6, 10) + sparse_double(1:4, 1:6, 10) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `value` (4) and `position` (6) must have the same length. --- Code - new_sparse_double(1, 1:6, 10) + sparse_double(1, 1:6, 10) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `value` (1) and `position` (6) must have the same length. --- Code - new_sparse_double(1:4, c(1, 1, 5, 6), 10) + sparse_double(1:4, c(1, 1, 5, 6), 10) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: x `position` must not contain any duplicate values. i Duplicate values at index: 2. --- Code - new_sparse_double(1:100, rep(1, 100), 100) + sparse_double(1:100, rep(1, 100), 100) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: x `position` must not contain any duplicate values. i Duplicate values at index: 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ..., 99, and 100. --- Code - new_sparse_double(c(1, 2), c(3, 1), 5) + sparse_double(c(1, 2), c(3, 1), 5) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: ! `position` must be sorted in increasing order. --- Code - new_sparse_double(1, 10, 5) + sparse_double(1, 10, 5) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: x `position` value must not be larger than `length`. i Offending values at index: 1. --- Code - new_sparse_double(rep(1, 50), seq(25, 74), 50) + sparse_double(rep(1, 50), seq(25, 74), 50) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: x `position` value must not be larger than `length`. i Offending values at index: 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, ..., 49, and 50. --- Code - new_sparse_double(1, 0, 5) + sparse_double(1, 0, 5) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: x `position` value must positive. i Non-positive values at index: 1. --- Code - new_sparse_double(rep(1, 101), seq(-50, 50), 100) + sparse_double(rep(1, 101), seq(-50, 50), 100) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: x `position` value must positive. i Non-positive values at index: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ..., 50, and 51. --- Code - new_sparse_double(0, 1, 10) + sparse_double(0, 1, 10) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: x `value` value must not be 0. i 0 values at index: 1. --- Code - new_sparse_double(rep(c(1, 0), 5), 1:10, 50) + sparse_double(rep(c(1, 0), 5), 1:10, 50) Condition - Error in `new_sparse_double()`: + Error in `sparse_double()`: x `value` value must not be 0. i 0 values at index: 2, 4, 6, 8, and 10. # verbose testing Code - new_sparse_double(1, 1, 1)[] + sparse_double(1, 1, 1)[] Output sparsevctrs: Sparse vector materialized [1] 1 diff --git a/tests/testthat/test-altrep.R b/tests/testthat/test-altrep.R index 423d867..055448e 100644 --- a/tests/testthat/test-altrep.R +++ b/tests/testthat/test-altrep.R @@ -1,167 +1,167 @@ test_that("input checking is done correctly", { expect_identical( - new_sparse_double(1L, 1, 1), - new_sparse_double(1, 1, 1) + sparse_double(1L, 1, 1), + sparse_double(1, 1, 1) ) # value expect_snapshot( error = TRUE, - new_sparse_double("1", 1, 1) + sparse_double("1", 1, 1) ) expect_snapshot( error = TRUE, - new_sparse_double(NULL, 1, 1) + sparse_double(NULL, 1, 1) ) expect_snapshot( error = TRUE, - new_sparse_double(NA, 1, 1) + sparse_double(NA, 1, 1) ) expect_snapshot( error = TRUE, - new_sparse_double(Inf, 1, 1) + sparse_double(Inf, 1, 1) ) expect_snapshot( error = TRUE, - new_sparse_double(NaN, 1, 1) + sparse_double(NaN, 1, 1) ) # position expect_snapshot( error = TRUE, - new_sparse_double(1, 1.5, 1) + sparse_double(1, 1.5, 1) ) expect_snapshot( error = TRUE, - new_sparse_double(1, "1", 1) + sparse_double(1, "1", 1) ) expect_snapshot( error = TRUE, - new_sparse_double(1, NULL, 1) + sparse_double(1, NULL, 1) ) expect_snapshot( error = TRUE, - new_sparse_double(1, NA, 1) + sparse_double(1, NA, 1) ) expect_snapshot( error = TRUE, - new_sparse_double(1, Inf, 1) + sparse_double(1, Inf, 1) ) expect_snapshot( error = TRUE, - new_sparse_double(1, NaN, 1) + sparse_double(1, NaN, 1) ) # length expect_no_error( - new_sparse_double(numeric(0), integer(0), 0) + sparse_double(numeric(0), integer(0), 0) ) expect_snapshot( error = TRUE, - new_sparse_double(numeric(0), integer(0), c(1, 10)) + sparse_double(numeric(0), integer(0), c(1, 10)) ) expect_snapshot( error = TRUE, - new_sparse_double(numeric(0), integer(0), 1.5) + sparse_double(numeric(0), integer(0), 1.5) ) expect_snapshot( error = TRUE, - new_sparse_double(numeric(0), integer(0), "1") + sparse_double(numeric(0), integer(0), "1") ) expect_snapshot( error = TRUE, - new_sparse_double(numeric(0), integer(0), NA) + sparse_double(numeric(0), integer(0), NA) ) expect_snapshot( error = TRUE, - new_sparse_double(numeric(0), integer(0), Inf) + sparse_double(numeric(0), integer(0), Inf) ) expect_snapshot( error = TRUE, - new_sparse_double(numeric(0), integer(0), NULL) + sparse_double(numeric(0), integer(0), NULL) ) expect_snapshot( error = TRUE, - new_sparse_double(numeric(0), integer(0), NaN) + sparse_double(numeric(0), integer(0), NaN) ) # Length restriction expect_snapshot( error = TRUE, - new_sparse_double(1:4, 1:6, 10) + sparse_double(1:4, 1:6, 10) ) expect_snapshot( error = TRUE, - new_sparse_double(1, 1:6, 10) + sparse_double(1, 1:6, 10) ) # duplicates in position expect_snapshot( error = TRUE, - new_sparse_double(1:4, c(1, 1, 5, 6), 10) + sparse_double(1:4, c(1, 1, 5, 6), 10) ) expect_snapshot( error = TRUE, - new_sparse_double(1:100, rep(1, 100), 100) + sparse_double(1:100, rep(1, 100), 100) ) # Ordered position expect_snapshot( error = TRUE, - new_sparse_double(c(1, 2), c(3, 1), 5) + sparse_double(c(1, 2), c(3, 1), 5) ) # Too large position values expect_snapshot( error = TRUE, - new_sparse_double(1, 10, 5) + sparse_double(1, 10, 5) ) expect_snapshot( error = TRUE, - new_sparse_double(rep(1, 50), seq(25, 74), 50) + sparse_double(rep(1, 50), seq(25, 74), 50) ) # Too large position values expect_snapshot( error = TRUE, - new_sparse_double(1, 0, 5) + sparse_double(1, 0, 5) ) expect_snapshot( error = TRUE, - new_sparse_double(rep(1, 101), seq(-50, 50), 100) + sparse_double(rep(1, 101), seq(-50, 50), 100) ) # Too large position values expect_snapshot( error = TRUE, - new_sparse_double(0, 1, 10) + sparse_double(0, 1, 10) ) expect_snapshot( error = TRUE, - new_sparse_double(rep(c(1, 0), 5), 1:10, 50) + sparse_double(rep(c(1, 0), 5), 1:10, 50) ) }) -test_that("length() works with new_sparse_double()", { +test_that("length() works with sparse_double()", { expect_identical( - length(new_sparse_double(numeric(), integer(), 0)), + length(sparse_double(numeric(), integer(), 0)), 0L ) expect_identical( - length(new_sparse_double(1, 1, 10)), + length(sparse_double(1, 1, 10)), 10L ) expect_identical( - length(new_sparse_double(1, 1, 100)), + length(sparse_double(1, 1, 100)), 100L ) }) -test_that("single subsetting works with new_sparse_double()", { - x_sparse <- new_sparse_double(value = c(10, 13, 20), position = c(1, 5, 8), 10) +test_that("single subsetting works with sparse_double()", { + x_sparse <- sparse_double(value = c(10, 13, 20), position = c(1, 5, 8), 10) x_dense <- c(10, 0, 0, 0, 13, 0, 0, 20, 0, 0) for (i in seq_len(10)) { @@ -186,8 +186,8 @@ test_that("single subsetting works with new_sparse_double()", { expect_identical(x_sparse[2.6], x_dense[2.6]) }) -test_that("multiple subsetting works with new_sparse_double()", { - x_sparse <- new_sparse_double(value = c(10, 13, 20), position = c(1, 5, 8), 10) +test_that("multiple subsetting works with sparse_double()", { + x_sparse <- sparse_double(value = c(10, 13, 20), position = c(1, 5, 8), 10) x_dense <- c(10, 0, 0, 0, 13, 0, 0, 20, 0, 0) expect_identical(x_sparse[1:2], x_dense[1:2]) @@ -217,8 +217,8 @@ test_that("multiple subsetting works with new_sparse_double()", { expect_identical(x_sparse[c(1, NaN)], x_dense[c(1, NaN)]) }) -test_that("materialization works with new_sparse_double()", { - x_sparse <- new_sparse_double(value = c(10, 13, 20), position = c(1, 5, 8), 10) +test_that("materialization works with sparse_double()", { + x_sparse <- sparse_double(value = c(10, 13, 20), position = c(1, 5, 8), 10) x_dense <- c(10, 0, 0, 0, 13, 0, 0, 20, 0, 0) expect_identical(x_sparse[], x_dense) @@ -226,7 +226,7 @@ test_that("materialization works with new_sparse_double()", { test_that("is_sparse_vector works", { - expect_true(is_sparse_vector(new_sparse_double(1, 1, 1))) + expect_true(is_sparse_vector(sparse_double(1, 1, 1))) expect_false(is_sparse_vector(c(1, 1, 1))) expect_false(is_sparse_vector(1:10)) @@ -237,6 +237,6 @@ test_that("verbose testing", { withr::local_options("sparsevctrs.verbose_materialize" = TRUE) expect_snapshot( - new_sparse_double(1, 1, 1)[] + sparse_double(1, 1, 1)[] ) }) diff --git a/tests/testthat/test-extractors.R b/tests/testthat/test-extractors.R index 4e43966..e6aa5a5 100644 --- a/tests/testthat/test-extractors.R +++ b/tests/testthat/test-extractors.R @@ -1,11 +1,11 @@ test_that(".positions works with altrep_sparse_double", { expect_identical( - .positions(new_sparse_double(1, 5, 10)), + .positions(sparse_double(1, 5, 10)), 5L ) expect_identical( - .positions(new_sparse_double(1:3, 5:7, 10)), + .positions(sparse_double(1:3, 5:7, 10)), 5:7 ) }) @@ -24,12 +24,12 @@ test_that(".positions works with numeric vectors", { test_that(".values works with altrep_sparse_double", { expect_identical( - .values(new_sparse_double(1, 5, 10)), + .values(sparse_double(1, 5, 10)), 1 ) expect_identical( - .values(new_sparse_double(1:3, 5:7, 10)), + .values(sparse_double(1:3, 5:7, 10)), c(1, 2, 3) ) }) From 7777410a0f72685e03fed391c59b9b3a69879c48 Mon Sep 17 00:00:00 2001 From: Emil Hvitfeldt Date: Tue, 7 May 2024 16:57:02 -0700 Subject: [PATCH 2/2] update readme --- README.Rmd | 6 +++--- README.md | 35 +++++++++++++++++------------------ 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/README.Rmd b/README.Rmd index 1ec1b35..6a2ae74 100644 --- a/README.Rmd +++ b/README.Rmd @@ -38,12 +38,12 @@ remotes::install_github("emilhvitfeldt/sparsevctrs") ```{r} library(sparsevctrs) -x <- new_sparse_vector(4, 7, 10) +x <- sparse_double(4, 7, 10) x sum(x) -new_sparse_vector(4, 7, 10) + new_sparse_vector(3, 2, 10) +sparse_double(4, 7, 10) + sparse_double(3, 2, 10) ``` This class is compatible with tibbles @@ -51,6 +51,6 @@ This class is compatible with tibbles ```{r} library(tibble) -tibble(x = sample(1:10), y = new_sparse_vector(1, 7, 10)) +tibble(x = sample(1:10), y = sparse_double(1, 7, 10)) ``` diff --git a/README.md b/README.md index b364b93..930154f 100644 --- a/README.md +++ b/README.md @@ -28,17 +28,16 @@ remotes::install_github("emilhvitfeldt/sparsevctrs") ``` r library(sparsevctrs) -x <- new_sparse_vector(4, 7, 10) +x <- sparse_double(4, 7, 10) x -#> #> [1] 0 0 0 0 0 0 4 0 0 0 sum(x) #> [1] 4 -new_sparse_vector(4, 7, 10) + new_sparse_vector(3, 2, 10) -#> -#> [1] 0 3 0 0 0 0 4 0 0 0 +sparse_double(4, 7, 10) + sparse_double(3, 2, 10) +#> [1] 3.456532e-314 2.847320e-314 2.714492e-314 2.927164e-314 4.940656e-323 +#> [6] 0.000000e+00 0.000000e+00 3.000000e+00 0.000000e+00 0.000000e+00 ``` This class is compatible with tibbles @@ -46,18 +45,18 @@ This class is compatible with tibbles ``` r library(tibble) -tibble(x = sample(1:10), y = new_sparse_vector(1, 7, 10)) +tibble(x = sample(1:10), y = sparse_double(1, 7, 10)) #> # A tibble: 10 × 2 -#> x y -#> -#> 1 10 0 -#> 2 6 0 -#> 3 5 0 -#> 4 4 0 -#> 5 1 0 -#> 6 8 0 -#> 7 2 1 -#> 8 7 0 -#> 9 9 0 -#> 10 3 0 +#> x y +#> +#> 1 10 0 +#> 2 6 0 +#> 3 5 0 +#> 4 4 0 +#> 5 1 0 +#> 6 8 0 +#> 7 2 1 +#> 8 7 0 +#> 9 9 0 +#> 10 3 0 ```