R - Установка класса объекта, созданного с помощью () - PullRequest
0 голосов
/ 27 декабря 2018

Сначала немного контекста:

В моем пакете 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 Ответ

0 голосов
/ 27 декабря 2018

Вы можете использовать метод 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

enter image description here

Чтобы восстановить исходную функцию позже, вы можетеdo 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, ...)
  }
}
...