如何group_by
在dplyr
类型链中使用时找出哪个组失败.举个例子:
library(dplyr)
data(iris)
iris %>%
group_by(Species) %>%
do(mod=lm(Petal.Length ~ Petal.Width, data = .)) %>%
mutate(Slope = summary(mod)$coeff[2])
Run Code Online (Sandbox Code Playgroud)
工作良好.现在,如果我将一些问题数据添加到iris
:
iris$Petal.Width[iris$Species=="versicolor"]= NA
Run Code Online (Sandbox Code Playgroud)
这样在尝试运行线性模型时失败:
iris_sub <- iris[iris$Species=="versicolor",]
lm(Petal.Length ~ Petal.Width, data = iris_sub)
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用大量数据集接近这个盲人,如果我运行它:
iris %>%
group_by(Species) %>%
do(mod=lm(Petal.Length ~ Petal.Width, data = .)) %>%
mutate(Slope = summary(mod)$coeff[2])
Run Code Online (Sandbox Code Playgroud)
此错误消息无法帮助我找到模型失败的级别:
lm.fit中的错误(x,y,偏移=偏移,singular.ok = singular.ok,...):0(非NA)情况
我可以使用如下的循环.这至少让我知道该Species
功能的哪个级别失败.但是,我更喜欢使用dplyr设置:
lmdf <- c()
for (i in unique(iris$Species)) {
cat(i, "\n")
u <- iris %>%
filter(Species==i) %>%
do(mod=lm(Petal.Length ~ Petal.Width, data = .))
lmdf = rbind(lmdf, u)
}
Run Code Online (Sandbox Code Playgroud)
有关更好的方法来实现这一点的任何建议吗?总而言之,我试图使用dplyr
类型框架来确定一个函数失败的组级别.
这里tryCatch
引用的解决方案似乎不再起作用.我收到此错误:
tryCatch出错(lm(v3~v4,df),error = if(e $ message == all_na_msg)默认值为stop(e)):找不到对象'e'
使用的完整示例purrr::safely
:
library(tidyverse)
data(iris)
iris$Petal.Width[iris$Species == "versicolor"] <- NA
Run Code Online (Sandbox Code Playgroud)
如果您对实际错误不感兴趣(即原因是什么0 (non-NA) cases
),您可以:
iris %>%
group_by(Species) %>%
do(mod = safely(lm)(Petal.Length ~ Petal.Width, data = .)$result) %>%
mutate(Slope = ifelse(!is.null(mod), summary(mod)$coeff[2], NA))
Run Code Online (Sandbox Code Playgroud)
我们完成了!
Source: local data frame [3 x 3]
Groups: <by row>
# A tibble: 3 × 3
Species mod Slope
<fctr> <list> <dbl>
1 setosa <S3: lm> 0.5464903
2 versicolor <NULL> NA
3 virginica <S3: lm> 0.6472593
Run Code Online (Sandbox Code Playgroud)
我们可以清楚地看到哪个组失败了(因为它NULL
代替了模型,而且它Slope
是未知的).此外,我们仍然为其他组获得了正确的模型和斜率,因此我们没有浪费计算时间(在较大的数据集上运行复杂模型时,这可能非常好).
step1 <- iris %>%
group_by(Species) %>%
do(res = safely(lm)(Petal.Length ~ Petal.Width, data = .)) %>%
mutate(err = map(list(res), 'error'),
mod = map(list(res), 'result'))
Run Code Online (Sandbox Code Playgroud)
不幸的是,我们不得不在list
那里使用额外的电话,不完全确定原因.或者,你可以ungroup
先.
要查看哪些(如果有)组有错误,我们可以使用:
filter(step1, !is.null(err))
Run Code Online (Sandbox Code Playgroud)
要首先抢救非错误组的结果filter
:
step1 %>%
filter(is.null(err)) %>%
mutate(Slope = summary(mod)$coeff[2])
Run Code Online (Sandbox Code Playgroud)
broom
如果想要获得整齐链中的模型系数,您还可以查看包.