Упс! Ошибки с кодом ООП S4 и загадочной ошибкой

Я пытаюсь настроить объект S4 и не могу понять, что с ним не так. Объект предназначен для облегчения печати множества демографических данных. Вот код:

dem <- setClass("dem", 
                slots = list(num_cats = "numeric",
                          cat_labels = "character",
                          cat_counts = "integer",
                          cat_percents = "character")
       )
setMethod("print", 
          "dem",
          function(.Object,
                   x = numeric(0)) {
              .Object <- dem
              paste(dem@num_cats)
          })

make_dem = function(dd) {
    dem(
        num_cats = length(dd$values),
        cat_labels = dd$values$value,
        cat_counts = dd$values$frequency,
        cat_percents = calc_dem_percents(cat_counts)
    ) }

Вот ссылочная функция calc_dem_percentsи извините за то, что не поместили его в первый тур:

calc_dem_percents <- function(cat_counts) { #calc percents for each category
    tot <- sum(cat_counts) #get total number of categories
    cat_counts <- cat_counts %>% as_tibble() #change to tibble because I do 
                                             # that
    percent(cat_counts$value/tot) # return percents as a list, one per cat
}

cat_counts происходит от dd$values$frequency,

Все проходит без ошибок. Затем, когда я использую

gender <- make_dem(dd)

я получил

##  Error in initialize(value, ...) : 
## no slot of name "refMethods" for this object of 
## "classRepresentation" 

Что я делаю неправильно? Я вижу много противоречивой документации и совершенно сбит с толку.

К вашему сведению, это структура dd:

List of 5    
 $ descript: chr "Gender"    
 $ units   : NULL    
 $ format  : NULL    
 $ counts  : Named num [1:3] 447 32 2    
  ..- attr(*, "names")= chr [1:3] "n" "missing" "distinct"    
 $ values  :List of 2    
  ..$ value    : chr [1:2] "Male" "Female"    
  ..$ frequency: num [1:2(1d)] 308 139    
 - attr(*, "class")= chr "describe"    

Спасибо!

2 ответа

Проблема почти наверняка в этой строке:

  cat_percents = calc_dem_percents(cat_counts)

Есть две вещи, которые могут быть неправильными:

  • вы ссылаетесь на функцию calc_dem_percents, которого не существует (вы написали это сами и забыли включить его в вопрос, или это из определенной библиотеки R?). Эта функция может содержать ошибку.
  • вы ссылаетесь на переменную cat_counts, но эта переменная еще не существует (она будет делать, если аргументы dem были названы, но это не так). Лучше использовать dd$values$frequency вместо.

Возможно, вы определили свою собственную переменную cat_counts (или объявил это как класс) вне рамок этого вопроса, и он использует это, но в этом случае я не могу вам помочь.

Если ничего из вышеперечисленного не работает, попробуйте оценить каждое из выражений, которые вы назначаете для слотов отдельно, и посмотрите, получите ли вы то, что ожидаете (в частности, обязательно проверьте class каждой из этих вещей).

@JDL, я выполнил ваше предложение использовать d$values$frequency вместо cat_counts и все еще была такая же ошибка. Затем я вернулся и прошел через make_dem_classТакже, как вы и предлагали, наблюдение за значениями обновляется по одному. И возникла проблема: первоначальное объявление cat_counts как часть дем класса. Я назвал это целым числом, но это было два целых числа, одно "число" для каждого "кота" или категории, число которых было cat_num- в этом случае 2. Когда я проверил класс объекта, из которого я брал cat_counts Я нашел:

class(dd$values$frequency)
# "array"

Так cat_counts должен был быть объявлен как массив, а не как целое число. Вот правильный код:

dem <- setClass("dem", 
                slots = list(num_cats = "numeric",
                             cat_labels = "character",
                             cat_counts = "array",
                             cat_percents = "character")
       )

    setMethod("print", 
              "dem",
              function(.Object,
                       x = numeric(0)) {
                  .Object <- dem
                  print(dem@cat_labels)
                  print(dem@cat_counts)
                  print(dem@cat_percents)
              })

    make_dem = function(dd) {
        dem(
            num_cats = length(dd$values),
            cat_labels = dd$values$value,
            cat_counts = dd$values$frequency,
            cat_percents = calc_dem_percents(dd$values$frequency)
        )
    }

И это работает. Большое спасибо.

Но следующего шага нет. С помощью make_dem_class() Я создал dem_objдемографический объект класса dem, Я сделал это так:

> dem_object <- make_dem_class(dd)
> dem_object

An object of class "dem"
Slot "num_cats":
[1] 2

Slot "cat_labels":
[1] "Male"   "Female"

Slot "cat_counts":
[1] 308 139

Slot "cat_percents":
[1] "68.9%" "31.1%"

Вот его структура:

> str(dem_object)
Formal class 'dem' [package ".GlobalEnv"] with 4 slots
  ..@ num_cats    : int 2
  ..@ cat_labels  : chr [1:2] "Male" "Female"
  ..@ cat_counts  : num [1:2(1d)] 308 139
  ..@ cat_percents: chr [1:2] "68.9%" "31.1%"

Но, похоже, что-то не так с моим setMethod для печати, потому что, когда я пытаюсь напечатать это, это происходит:

Error in print(dem@cat_labels) : 
  no slot of name "cat_labels" for this object of class "classGeneratorFunction" 

Так много узнать о работе с объектами S4.,,,

Другие вопросы по тегам