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(), что облегчает пользователям получение правильных, оптимальных результатов.

До сих пор я думал о следующих решениях:

  1. Добавление аргумента "by" к функциям, чтобы у меня был полный контроль над пропорциями созданных объектов. Мне не нравится это решение, так как 1) я пытаюсь опираться на базовые функции R, с которыми знакомы люди, а не вводить новые параметры, и 2) у меня все еще будет похожая проблема, когда объекты создаются с lapply(),
  2. переосмысление by() так что, когда он вызывается из одной из функций summarytools, он добавляет нужный класс к созданным объектам. Я избегал этого, потому что не решаюсь переопределять базовые функции. Я бы предпочел не видеть сообщений о том, что объекты были замаскированы при загрузке пакета.
  3. Определение конкретного пакета 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, ...)
  }
}
Другие вопросы по тегам