R - Установка класса объекта, созданного с помощью ()
Сначала немного контекста:
В моем пакете summarytools я определил print
метод для объектов класса "summarytools". Я также создал функцию view()
который обрабатывает объекты, созданные с использованием by()
или же lapply()
таким образом, что вывод не включает в себя строки, указывающие группу - или переменную в случае lapply()
; summarytools отображает свои собственные заголовки, содержащие эту информацию, поэтому при использовании возникает некоторая избыточность print
, Кроме того, основные заголовки не повторяются при использовании view()
,
Вот пример. Обратите внимание, что в этой версии (в разработке), я включил сообщение, рекомендующее использование view()
:
> library(summarytools)
> (tmp <- with(tobacco, by(smoker, gender, freq)))
gender: F
For best results printing list objects with summarytools, use view(x, method = 'pander')
Frequencies
tobacco$smoker
Type: Factor
Group: gender = M
Freq % Valid % Valid Cum. % Total % Total Cum.
----------- ------ --------- -------------- --------- --------------
Yes 147 30.06 30.06 30.06 30.06
No 342 69.94 100.00 69.94 100.00
<NA> 0 0.00 100.00
Total 489 100.00 100.00 100.00 100.00
------------------------------------------------------------------
gender: M
Frequencies
tobacco$smoker
Type: Factor
Group: gender = F
Freq % Valid % Valid Cum. % Total % Total Cum.
----------- ------ --------- -------------- --------- --------------
Yes 143 29.24 29.24 29.24 29.24
No 346 70.76 100.00 70.76 100.00
<NA> 0 0.00 100.00
Total 489 100.00 100.00 100.00 100.00
А теперь с помощью view()
:
> view(tmp, method = "pander")
Frequencies
tobacco$smoker
Type: Factor
Group: gender = M
Freq % Valid % Valid Cum. % Total % Total Cum.
----------- ------ --------- -------------- --------- --------------
Yes 147 30.06 30.06 30.06 30.06
No 342 69.94 100.00 69.94 100.00
<NA> 0 0.00 100.00
Total 489 100.00 100.00 100.00 100.00
Group: gender = F
Freq % Valid % Valid Cum. % Total % Total Cum.
----------- ------ --------- -------------- --------- --------------
Yes 143 29.24 29.24 29.24 29.24
No 346 70.76 100.00 70.76 100.00
<NA> 0 0.00 100.00
Total 489 100.00 100.00 100.00 100.00
Я думал о том, каким образом объекты класса "by" будут автоматически отправляться view()
вместо print()
, Если я добавлю класс "summarytools" к этим объектам, print()
метод может перенаправить вызов view()
, что облегчает пользователям получение правильных, оптимальных результатов.
До сих пор я думал о следующих решениях:
- Добавление аргумента "by" к функциям, чтобы у меня был полный контроль над пропорциями созданных объектов. Мне не нравится это решение, так как 1) я пытаюсь опираться на базовые функции R, с которыми знакомы люди, а не вводить новые параметры, и 2) у меня все еще будет похожая проблема, когда объекты создаются с
lapply()
, - переосмысление
by()
так что, когда он вызывается из одной из функций summarytools, он добавляет нужный класс к созданным объектам. Я избегал этого, потому что не решаюсь переопределять базовые функции. Я бы предпочел не видеть сообщений о том, что объекты были замаскированы при загрузке пакета. - Определение конкретного пакета
by()
, такие какby_st()
; Я мог бы использовать в основном тот же код, что иby.default()
а такжеby.data.frame()
единственное отличие состоит в том, что я добавляю класс "summarytools" к созданным объектам. Это своего рода компромисс, который я рассматриваю.
У меня следующий вопрос: могут ли быть другие, может быть, лучшие решения, которых я не вижу?
1 ответ
Вы можете использовать метод S3 для print.by
отправить к вашей пользовательской функции:
old.print.by = print.by # save the original function so we can restore it later
print.by = summarytools::view # redefine print.by to dispatch to custom function
tmp
h ttps://stackru.com/images/dd550ef7e457cf9450fedc053b7bb31de6e7007d.png
Чтобы восстановить исходную функцию позже вы можете сделать print.by = old.print.by
,
Если вы хотите, чтобы ваша новая функция работала со списками, которые содержат объекты класса "summarytools", вы можете использовать
print.by = function(x, method = 'pander', ...) {
if ("summarytools" %in% class(x[[1]])) {
summarytools::view(x, method, ...)
} else {
old.print.by(x, ...)
}
}