Определение класса vctrs S3, который будет действовать как ключ (уникальный, без пропущенных значений) - PullRequest
0 голосов
/ 18 марта 2020

Я пытаюсь определить новый класс вектора, используя пакет vctrs в R. Надежда состоит в том, что вектор может выступать в качестве «ключа» или «индекса» (без пропущенных значений и без повторяющихся записей). Реализация basi c кажется достаточно простой (если вы прочитали документацию vctrs: https://vctrs.r-lib.org/articles/s3-vector.html).

library(vctrs)
library(assertthat)

#' A character vector guaranteed to be unique with no missing values
key <- function(x = character()) {
    new_key(vec_cast(x, character()))
}

new_key <- function(x = character()) {
    vec_assert(x, character())
    assert_that(!any(is.na(x)), !any(duplicated(x)))
    new_vctr(x, class = "key")
}

is_key <- function(x) inherits(x, "key")

as_key <- function(x) vec_cast(x, new_key())

# vec_ptype2
vec_ptype2.key <- function(x, y, ...) UseMethod("vec_ptype2.key", y)

vec_ptype2.key.default <- function(x, y, ..., x_arg = "x", y_arg = "y") {
    vec_default_ptype2(x, y, x_arg = x_arg, y_arg = y_arg)
}

vec_ptype2.key.key <- function(x, y, ...) new_key()

vec_ptype2.key.character <- function(x, y, ...) character()

vec_ptype2.character.key <- function(x, y, ...) character()


# vec_cast
vec_cast.key <- function(x, to, ...) UseMethod("vec_cast.key")

vec_cast.key.default <- function(x, to, ...) vec_default_cast(x, to)

vec_cast.key.key <- function(x, to, ...) x

vec_cast.key.character <- function(x, to, ...) key(x)

vec_cast.character.key <- function(x, to, ...) vec_data(x)

Реализация basi c работает в основном так, как и ожидалось:

x <- key(letters[1:5]) # creates a key
key(c("a", "b", "a")) # fails due to duplicate entry
key(c("a", "b", NA)) # fails due to missing entry

Однако мы начинаем сталкиваться с некоторыми проблемами при соединении ключей и с vec_init:

vec_init(key(), 5) # gives a vector of NAs and it seems there's no way round this
vec_c(x, x) # now we have a vector with non-unique entries

Я чувствую, что должно быть решение для использования vec_restore, но я могу не совсем поняла. Любая помощь в завершении этого класса приветствуется. Или, возможно, это просто невозможно определить с помощью Vctrs?

...