【问题标题】:Broom/Dplyr error with glance() when using lm instead of biglm使用 lm 而不是 biglm 时 Glance() 出现 Broom/Dplyr 错误
【发布时间】:2016-05-08 06:22:15
【问题描述】:

我正在使用 dplyr/broom 包对多个传感器进行线性回归。当我在 do 语句中使用 lm() 时,broom 中的glance() 函数将不起作用,但如果我使用 biglm() 则将起作用。这不是问题,但我想要 r^2、F-Statistic 和 p-val,对于传统的 lm(),glance 返回相当漂亮。

我在别处找过,找不到类似的错误:

Error in data.frame(r.squared = r.squared, adj.r.squared = adj.r.squared,  : 
 object 'fstatistic' not found

可能的预感:

?Anova 
"The comparison between two or more models will only be valid if they are 
fitted to the same dataset. This may be a problem if there are missing
values and R's default of na.action = na.omit is used."

代码如下:

library(tidyr)
library(broom)
library(biglm) # if not install.packages("biglm")
library(dplyr)
regressionBig <- tidied_rm_outliers %>%
group_by(sensor_name, Lot.Tool, Lot.Module, Recipe, Step, Stage, MEAS_TYPE) %>%
do(fit = biglm(MEAS_AVG ~ value, data = .)) #note biglm is used

regressionBig 

#extract the r^2 from the complex list type from the data frame we just stored

glances <- regressionBig %>% glance(fit)
glances %>% 
  ungroup() %>%
  arrange(desc(r.squared))
#Biglm works but if i try the same thing with regular lm It errors on glance() 

ErrorDf <- tidied_rm_outliers %>%
  group_by(sensor_name, Lot.Tool, Lot.Module, Recipe, Step, Stage, MEAS_TYPE) %>% 
  do(fit = lm(MEAS_AVG ~ value, data = .)) #note lm is normal
ErrorDf %>% glance(fit)

#Error in data.frame(r.squared = r.squared, adj.r.squared = adj.r.squared,  : 
#object 'fstatistic' not found

我讨厌上传整个数据框,因为我知道这在 S/O 上通常是不可接受的,但我不确定如果不这样做我是否可以创建可重现的示例。 https://www.dropbox.com/s/pt6xe4jdxj743ka/testdf.Rda?dl=0

pastebin 上的 R 会话信息,如果您愿意的话here

【问题讨论】:

  • 当由于模型奇异性而没有定义至少一个系数并且因此在 lm 对象中没有返回 F 统计量时,我可以重现这一点 - 所以 glance 字面上找不到 @987654328 @.

标签: r dplyr


【解决方案1】:

ErrorDf 中的模型看起来很糟糕。我诊断它运行for 循环。

for (i in 1:nrow(ErrorDf)){
  print(i)
  glance(ErrorDf$fit[[i]])
}

看起来value 的系数无法为模型#94 估计。我没有做任何进一步的调查,但它提出了一个有趣的问题,即broom 应该如何处理这个问题。

【讨论】:

    【解决方案2】:

    在遇到同样的问题后,我偶然发现了这篇文章。如果lm() 失败是因为某些分组的案例太少,那么您可以通过在运行do() 循环之前预先过滤数据以删除这些分组来解决问题。下面的通用代码显示了如何过滤掉少于 30 个数据点的组。

    require(dplyr)
    require(broom)
    
    data_grp = ( data 
        %>% group_by(factor_a, factor_b)
        %>% mutate(grp_cnt=n())
        %>% filter(grp_cnt>30)
    )
    

    【讨论】:

      【解决方案3】:

      在我的故障排除中找到这篇文章后,我编写了一个函数来处理这个问题。包维护者可能(将)有一个更聪明的解决方案,但我认为它应该适用于大多数情况。感谢 @Benjamin 提供循环灵感。

      collect_glance=function(mdldF){
          # mdldF should be a data frame from dplyr/broom with the column 'mdl' for the object models
          mdlglance=data_frame() #initialize empty dataframe
          metadF=mdldF %>% slice(0) %>% select(-ncol(mdldF))#create an empty data frame with only the group info
          i=1
          for(i in 1:nrow(mdldF)){
              # fill in metadata for each group for each modeling iteration
              for(colnums in 1:ncol(mdldF)-1){
                  metadF[1,colnames(mdldF)[colnums]]=mdldF[i,colnames(mdldF[colnums])]
              }
              # attempt glance(). if succesful, bind to metadata. if not, return empty dataframe
              gtmp=tryCatch(glance(mdldF$mdl[[i]]) %>% bind_cols(metadF,.), error = function(e) {
                  data_frame()
              })
              # test for empty dataframe. bind to mdlglance data frame if glance was successful. otherwise use full_join to join mdlglance and metadata by group names and get NA for all the other glance columns.
              if(nrow(gtmp)!=0) { 
                  mdlglance=bind_rows(mdlglance,gtmp) 
              } else {
                  mdlglance=full_join(mdlglance,metadF)
                  }
          }
          return(mdlglance)
      }
      

      【讨论】:

        猜你喜欢
        • 2015-11-21
        • 2018-04-03
        • 2018-02-02
        • 2018-02-02
        • 1970-01-01
        • 1970-01-01
        • 2014-03-11
        • 2012-10-26
        • 1970-01-01
        相关资源
        最近更新 更多