Упс! Ошибки с кодом ООП 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.,,,