Упс! Ошибки с кодом ООП S4 и загадочной ошибкой - PullRequest
0 голосов
/ 28 августа 2018

Я пытаюсь настроить объект 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 ]

0 голосов
/ 03 сентября 2018

@ JDL, я выполнил ваше предложение использовать d$values$frequency вместо cat_counts и все еще имел ту же ошибку. Затем я вернулся и прошел по make_dem_class, также, как вы и предлагали, наблюдая, как значения обновляются один за другим. И была проблема: первоначальное объявление cat_counts как часть класса dem. Я назвал его целым числом, но это было два целых числа, по одному «count» для каждого «кота» или категории, число которых было 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. , , .

0 голосов
/ 31 августа 2018

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

  cat_percents = calc_dem_percents(cat_counts)

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

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

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

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

...