-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a664a50
commit 14c3884
Showing
8 changed files
with
236 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#' @describeIn indices Construct an `indices` list with minimal checks | ||
#' @export | ||
new_indices <- function(x = list()) { | ||
if (!is.list(x)) { | ||
cli_abort("{.arg x} must be a list.") | ||
} | ||
|
||
vctrs::new_vctr(x, class="indices") | ||
} | ||
|
||
#' Construct a list of indices | ||
#' | ||
#' An `indices` list is a list with integer vector entries which represent | ||
#' indices in some other object (like a data frame). Generically it can | ||
#' be used to represent a graph structure, such as an interference network | ||
#' or a collection of matched objects. | ||
#' The main feature of `indices` is that the index references are preserved | ||
#' through slicing and reordering. Indices that no longer refer to elements | ||
#' (because of subsetting) are set to NA. | ||
#' | ||
#' @param x | ||
#' * For `indices()` and `new_indices()`: A list of indices | ||
#' * For `is_indices()`: An object to test | ||
#' * For `as_indices()`: An object to coerce | ||
#' | ||
#' @returns An `indices` object. | ||
#' | ||
#' @examples | ||
#' idx <- indices(list(2, c(1, NA, 3), 2)) | ||
#' print(idx) | ||
#' idx[1:2] # subsetting | ||
#' idx[c(2, 1, 3)] # reordering | ||
#' @export | ||
indices <- function(x = list()) { | ||
# convert each element to an integer | ||
x <- relist(vctrs::vec_cast(unlist(x), integer(), x_arg="x"), x) | ||
new_indices(x) | ||
} | ||
|
||
#' @describeIn indices Return `TRUE` if an object is an `indices` list | ||
#' @export | ||
is_indices <- function(x) { | ||
inherits(x, "indices") | ||
} | ||
|
||
#' @describeIn indices Coerce an object to an `indices` list | ||
#' @export | ||
as_indices <- function(x) { | ||
vctrs::vec_cast(x, new_indices()) | ||
} | ||
|
||
|
||
# printing | ||
#' @export | ||
format.indices <- function(x, ...) { | ||
vapply(vctrs::vec_data(x), format_index_line, "") | ||
} | ||
format_index_line <- function(y) { | ||
paste0("(", paste0(formatC(y[!is.na(y)]), collapse=","), ")") | ||
} | ||
|
||
# vctrs ------------------------------------------------------------------- | ||
|
||
#' @export | ||
`[.indices` <- function(x, i) { | ||
lookup <- match(seq_along(x), i) | ||
out <- NextMethod() | ||
for (j in seq_along(out)) { | ||
out[[j]] = lookup[out[[j]]] | ||
} | ||
out | ||
} | ||
|
||
#' @importFrom vctrs vec_ptype_abbr | ||
#' @method vec_ptype_abbr indices | ||
#' @export | ||
vec_ptype_abbr.indices <- function(x, ...) { | ||
"idx" # nocov | ||
} | ||
|
||
#' @importFrom vctrs vec_ptype2 | ||
#' @export | ||
vec_ptype2.list.indices <- function(x, y, ...) list() | ||
#' @export | ||
vec_ptype2.indices.list <- function(x, y, ...) list() | ||
#' @importFrom vctrs vec_cast | ||
#' @export | ||
vec_cast.list.indices <- function(x, y, ...) as.list(x) | ||
#' @export | ||
vec_cast.indices.list <- function(x, y, ...) indices(x) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# indices printing | ||
|
||
Code | ||
print(idx) | ||
Output | ||
<indices[3]> | ||
[1] (2) (1,3) (2) | ||
|
||
--- | ||
|
||
Code | ||
str(idx) | ||
Output | ||
idx [1:3] | ||
$ : int 2 | ||
$ : int [1:3] 1 NA 3 | ||
$ : int 2 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
test_that("indices constructor", { | ||
idx <- indices(list(2, c(1, NA, 3), 2)) | ||
expect_s3_class(idx, "indices") | ||
expect_type(idx, "list") | ||
expect_true(is_indices(idx)) | ||
|
||
expect_error(indices(list("a")), "character") | ||
expect_error(indices(5), "must be a list") | ||
}) | ||
|
||
test_that("indices conversion", { | ||
idx <- indices(list(2, c(1, NA, 3), 2)) | ||
|
||
expect_s3_class(as_indices(as.list(idx)), "indices") | ||
expect_type(as.list(idx), "list") | ||
expect_type(c(idx, list()), "list") | ||
expect_type(c(list(), idx), "list") | ||
}) | ||
|
||
test_that("indices slicing", { | ||
idx <- indices(list(2, c(1, NA, 3), 2)) | ||
|
||
expect_equal(idx[1:3], idx) | ||
expect_equal(idx[1:2], | ||
indices(list(2, c(1, NA, NA)))) | ||
expect_equal(idx[2:1], | ||
indices(list(c(2, NA, NA), 1))) | ||
}) | ||
|
||
|
||
test_that("indices printing", { | ||
idx <- indices(list(2, c(1, NA, 3), 2)) | ||
|
||
expect_snapshot(print(idx)) | ||
expect_snapshot(str(idx)) | ||
}) |