【问题标题】:broom::tidy() with do() in a dplyr workflow fails with a summaryDefault objectdplyr 工作流程中带有 do() 的 broom::tidy() 失败,并带有一个 summaryDefault 对象
【发布时间】:2015-11-23 22:03:10
【问题描述】:

我想对 data.frame 中的变量进行数字汇总(基础包中的summary.default())并在 broom 包中使用 tidy(),但这不知何故失败了。

在这个例子中,我创建了一个data.frame:

df <- data.frame(group = c(rep('M', 6), 'F', 'F', 'M', 'M', 'F', 'F'),
                 val = c(6, 5, NA, NA, 6, 13, NA, 8, 10, 7, 14, 6))

我加载 plyr (1.8.3)、dplyr (0.4.2) 和 broom (0.3.7)(按此顺序)。仅供参考在 64 位 Windows 上运行 R 3.2.2,但我在 Unix 上遇到与 3.2.1 类似的问题。

我认为这会给我一个理想的输出:

df %>% group_by(group) %>% do(tidy(summary(.$val)))

但我收到一条错误消息:

Error: corrupt data frame at index 1

我可以使用plyr 方法和broom::tidy 获得理想的结果,如下所示:

df %>% group_by(group) %>% do(summ = summary(.$val)) %>% 
    daply(.(group), function(x) tidy(x$summ[[1]]))

group minimum q1 median mean  q3   maximum <NA>
    F 6       7  8      9.333 11   14      1   
    M 5       6  6.5    7.833 9.25 13      2  

但显然我问这个问题是为了解决问题的根源,如上所述在 do() 函数中使用 tidy() (summaryDefault)。

【问题讨论】:

  • NAs in df 正在制造问题。如果在用整数替换 NAs 后运行相同的代码,代码运行良好。
  • 试试df[complete.cases(df),] %&gt;% group_by(group) %&gt;% do(tidy(summary(.$val)))
  • summaryDefault tidy 为 NA 生成了一个额外的列,所以这仍然是一个问题,但感谢 @Narendra 缩小范围

标签: r broom


【解决方案1】:

tl;dr 这看起来像broom:::tidy.summaryDefault 中的一个错误(我报告了它here),它假定摘要对象只有 6 个元素(不是 7 个,就像数据中有NA 值)。它看起来很容易修复,但我现在没有时间......

我使用options(error=recover) 来查看问题出在哪里。根据以下内容,我认为问题与列名中的 "NA" 有关,在某些时候必须以非标准方式进行评估:

当事情破裂时,我们将做rbind_all(out[[1]])。这是我们所拥有的:

 str(out[[1]])
List of 2
 $ :'data.frame':   1 obs. of  7 variables:
  ..$ minimum: num 6
  ..$ q1     : num 7
  ..$ median : num 8
  ..$ mean   : num 9.33
  ..$ q3     : num 11
  ..$ maximum: num 14
  ..$ NA     : num 1
 $ :'data.frame':   1 obs. of  7 variables:
  ..$ minimum: num 5
  ..$ q1     : num 6
  ..$ median : num 6.5
  ..$ mean   : num 7.83
  ..$ q3     : num 9.25
  ..$ maximum: num 13
  ..$ NA     : num 2

如果我重命名组件数据框,一切都很好:

Browse[1]> rbind_all(lapply(out[[1]],setNames,letters[1:7]))
Source: local data frame [2 x 7]

      a     b     c     d     e     f     g
  (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl)
1     6     7   8.0 9.333 11.00    14     1
2     5     6   6.5 7.833  9.25    13     2

如果我只重命名有问题的列,它也可以:

 ff <- function(x) { names(x)[7] <- ".NA"; x }
Browse[1]> rbind_all(lapply(out[[1]],ff))
Source: local data frame [2 x 7]

  minimum    q1 median  mean    q3 maximum   .NA
    (dbl) (dbl)  (dbl) (dbl) (dbl)   (dbl) (dbl)
1       6     7    8.0 9.333 11.00      14     1
2       5     6    6.5 7.833  9.25      13     2

所以最好的办法可能是对broom::tidy 进行破解/功能请求,它以某种更受保护的方式指定NA 列(.NA_NAnumNA、...)

实际上,这看起来像是summaryDefault 中的一个错误。该函数的内容是

ret <- as.data.frame(t(as.matrix(x)))
colnames(ret) <- c("minimum", "q1", "median", "mean", "q3", 
    "maximum")
ret

这并没有考虑到摘要中可能有一个NA's 列的事实。也就是说,names(ret)[7]实际 NA 值,而不是 "NA" ...

【讨论】:

    猜你喜欢
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多