Создать класс S4, наследующий от фрейма данных - PullRequest
1 голос
/ 17 апреля 2020

Я пишу пакет R. В этом пакете я хотел бы sh иметь специальный тип фрейма данных, который могут распознавать некоторые функции, скажем, с некоторыми дополнительными атрибутами, но в остальном он ведет себя точно так же, как фрейм данных. Один из способов добиться того, чего я хочу, это просто установить некоторые атрибуты в обычном фрейме данных:

   makedf <- function() {
     df <- data.frame(ID=1:3)
     attr(df, "myDF") <- TRUE
     attr(df, "source") <- "my nose"
     return(df)
   }

   dosmth <- function(df) {
     if(!is.null(attr(df, "myDF"))) message(sprintf("Oh my! My DF! From %s!", attr(df, "source")))
     message(sprintf("num of rows: %d", nrow(df)))
   }

Когда dosmth() получает «myDF», у него есть дополнительная информация об источнике фрейма данных:

dosmth(data.frame(1:5))
#> num of rows: 5
dosmth(makedf())
#> Oh my! My DF! From my nose!
#> num of rows: 3

Точно так же было бы довольно просто с S3, и мы могли бы даже написать разные варианты доз, используя преимущества метода. Как мне это сделать с S4?

1 Ответ

2 голосов
/ 17 апреля 2020

Я не совсем уверен, что это то, что вы ищете, но звучит так, как будто вы хотите иметь возможность определить обобщенную c функцию, которая специализируется для ваших MyDF и data.frame, например this представьте

MyDF <- setClass(Class = "MyDF",
                 slots = c(source = "character"),
                 contains = c("data.frame"))

setGeneric("dosmth", function(x) message("Can only dosmth to a df or MyDF"))

setMethod("dosmth", signature("data.frame"), 
          function(x) message(sprintf("num of rows: %d", nrow(x))))

setMethod("dosmth", signature("MyDF"), 
          function(x)  message(sprintf("Oh my! My DF! From %s!", x@source)))

a_df   <- data.frame(a = 1, b = 2)
a_MyDF <- MyDF(a_df, source = "my nose")

dosmth("my nose")
#> Can only dosmth to a df or MyDF
dosmth(a_df)
#> num of rows: 1
dosmth(a_MyDF)
#> Oh my! My DF! From my nose!

Спасибо @JDL за комментарий, указывающий, что нам не нужен дополнительный слот "data.frame", так что поведение data.frame может быть унаследовано правильно, как в следующем примере показывает:

a_MyDF[1,]
#>   a b
#> 1 1 2

Создано в 2020-04-17 пакетом Представить (v0.3.0)

...