Как написать функцию AC () для пользовательского класса S3 в R
Вопрос
Я пишу класс S3 в R, это просто целое число с некоторыми атрибутами, прилагаемыми к нему. Если X1 и X2 являются объектами этого класса (вызовите его «MyClass»), то я бы хотел C (x1, x2), чтобы вернуть вектор объектов MyClass с оригинальным определением класса и атрибутами Intact. Однако документированное поведение C () состоит в том, чтобы удалить атрибуты, поэтому казалось бы, что мне нужно написать свой собственный метод C.MyClass (). Мой вопрос в том, как я могу это сделать?
Пример проблемы:
myclass <- function(x, n) structure(x, class="myclass", n=n)
x1 <- myclass(1, 5)
x2 <- myclass(2, 6)
c(x1, x2)
[1] 1 2
Здесь результат - это просто вектор элементов класса Numeric, а исходный N атрибут исчез.
Глядя на код для различных пакетов, я иногда вижу код, как следующее, в котором нам нужно сохранить атрибут класса, но ничего другого:
c.myclass <- function(..., recursive = F) {
structure(c(unlist(lapply(list(...), unclass))), class="myclass")
}
К сожалению, я также не могу получить это на работу. Результат вызова C.myclass (x1, x2) - это вектор, где сам вектором имеет класс «MyClass», но где каждый элемент в векторе имеет числовое число; Я действительно хочу каждый элемент в векторе, чтобы иметь класс «MyClass». На практике мне также нужно будет обновить этот метод, чтобы сохранить другие атрибуты, а также атрибут «N» в MyClass).
Решение
Это работает, но я предполагаю, что вы пришли к выводу, что каждый элемент элемента вектора имеет класс, потому что вы делаете что-то подобное:
foo <- c(x1, x2)
class(foo[1])
class(foo[2])
Если это так, и вы хотите извлечь элементы, чтобы сохранить myclass
атрибут, вам нужно написать метод подмножества "[.myclass"
сохранить атрибуты.
Другие советы
Вот пример, который делает (я думаю), что вы хотите по конкретным методам для c
а также [
:
c.myclass <- function(..., recursive = FALSE) {
dots <- list(...)
ns <- sapply(dots, attr, which = "n")
classes <- rep("myclass", length(dots))
res <- structure(unlist(dots, recursive = FALSE), class = classes)
attr(res, "n") <- ns
res
}
`[.myclass` <- function (x, i) {
y <- unclass(x)[i]
ns <- attr(x, "n")[i]
class(y) <- "myclass"
attr(y, "n") <- ns
y
}
myclass <- function(x, n) structure(x, class = "myclass", n = n)
x1 <- myclass(1, 5)
x2 <- myclass(2, 6)
c(x1, x2)
c(x1, x2)[2]
Но это выдумка в том, что мы должны управлять обработкой настроек и подвеска дополнительных атрибутов для удержания n
. Отказ Это действительно просто числовой вектор с атрибутом для записи n
.
Может быть более естественным для работы с университетом всех векторов, список. Бит, который более вовлечен, и, возможно, приведен выше в вашем случае?