Я пытаюсь определить новый класс вектора, используя пакет 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?