使用带有段错误的总结时 dplyr 崩溃

dplyr crashes when using summarise with segfault error

我的 dplyr 脚本有时会在此代码段中崩溃:

abc.fit <- abc_bySubject %>%
  do(fit = lm(value ~ delta, .)) %>%
  summarise(fvc_intercept = coef(fit)[1],
        fvc_slope = coef(fit)[2])

崩溃错误是:

 *** caught segfault ***
address 0x7ff041000098, cause 'memory not mapped'

然而,当我在 Rstudio 中执行此部分并出现错误 fatal error - R Session Aborted 时,也会发生这种情况,但频率较低。当我在 R 命令行中获取脚本时,它总是会发生。 我在具有大量 RAM 的不同机器上对其进行了测试。 R 和所有软件包都是最新的,我使用的是最新版本的 Ubuntu。

可能与这个问题有关:link但它说这是固定的。

也许有更好的解决方案

另一个不使用 summarise(OP 的代码在 dplyr_0.4.1.9000 中工作)来获得预期输出的选项是从 lm 中提取 coef,将其转换为list,更改列表元素(setNames)的'names',并在do环境中转换回data.frame

library(dplyr)
abc.fit <- abc_bySubject %>%
                do(data.frame(setNames(as.list(coef(lm(value~delta, data=.))),
                            c('fvc_intercept','fvc_slope' ))))

abc.fit
#    Subject fvc_intercept   fvc_slope
#1       1     0.5319503 -0.03147698
#2       2     0.4478791  0.04293860
#3       3     0.4318059 -0.03276570

如果我们需要删除'Subject'列,我们可以ungroup()并使用select到select除'Subject'[=32=以外的列]

abc.fit %>% 
      ungroup() %>%
      select(-Subject)
#  fvc_intercept   fvc_slope
#1     0.5319503 -0.03147698
#2     0.4478791  0.04293860
#3     0.4318059 -0.03276570

另一个选项是 data.table。我们将'data.frame'转换为'data.table'(setDT(abc)),按'Subject'列分组,我们得到lm的系数(coef),转换为 list (as.list) 并设置列的名称 (setnames).

 library(data.table)
 res <- setnames(setDT(abc)[, as.list(coef(lm(value~delta))),
               by =Subject],2:3, c('fvc_intercept', 'fvc_slope'))[]
 res
 #   Subject fvc_intercept   fvc_slope
 #1:       1     0.5319503 -0.03147698
 #2:       2     0.4478791  0.04293860
 #3:       3     0.4318059 -0.03276570

我们可以从 'res'

中对感兴趣的列进行子集化
res[,-1, with=FALSE]
#   fvc_intercept   fvc_slope
#1:     0.5319503 -0.03147698
#2:     0.4478791  0.04293860
#3:     0.4318059 -0.03276570

数据

set.seed(24)
abc <- data.frame(Subject= rep(1:3,each=10), delta=rnorm(30), value=runif(30))
abc_bySubject <- group_by(abc, Subject)