R-设置由by()创建的对象的类

时间:2018-12-26 23:59:52

标签: r grouping lapply summarytools

首先介绍一下上下文:

在我的软件包summarytools中,我为“ summarytools”类的对象定义了一种print方法。我还创建了一个函数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)使用{{1创建对象时,我仍然会遇到类似的问题}}。
  2. 重新定义lapply(),以便从summarytools函数之一调用它时,它将所需的类附加到创建的对象上。我避免了这一点,因为我不愿意重新定义基本函数。我宁愿不要看到这样的消息,即在装入程序包时已掩盖了对象。
  3. 定义特定于软件包的by(),例如by();我可以使用与by_st()by.default()基本上相同的代码,唯一的不同是我将“ summarytools”类添加到创建的对象中。这是我正在考虑的一种折衷方案。

我的问题如下:还有其他我可能看不到的更好的解决方案吗?

1 个答案:

答案 0 :(得分:3)

您可以对print.by使用S3方法来分派到您的自定义函数:

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

要稍后恢复原始功能,您可以执行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, ...)
  }
}