从统计角度来看,@astrofunkswag 所说的是正确的。您必须定义统计标准以避免出现曲线。对我们来说幸运的是,使用broom 包可以复制geom_smooth() 中的函数并将所有必需的统计信息保存在数据框中,以评估模型的好坏。在这里,我将向您展示如何制作一种统计过滤器的代码。首先是数据:
library(ggplot2)
library(broom)
library(dplyr)
#Data
df4 <- data.frame(group = c("a", "a", "a", "a", "a", "b", "b", "b", "b", "b",
"c", "c", "c", "c", "c", "d", "d", "d", "d", "d"),
pop = c(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5),
value = c(1,2,3,2.5,2,2,3,4,3.5,3,3,2,1,2,2.5,0.5,1.5,6,2,1.5))
现在,我们将按组复制geom_smooth() 中的模型,并将不同的统计信息保存在新的数据框中:
#Fit models by group
df5 <- df4 %>% group_by(group) %>%
do(fitmod = glance(lm(value ~ poly(pop,2), data = .))) %>%
unnest(fitmod) %>% dplyr::select(group,r.squared)
在之前的代码中,我只选择了r.squared,但这些都是拟合模型的统计数据:
# A tibble: 4 x 12
group r.squared adj.r.squared sigma statistic p.value df logLik AIC BIC deviance
<fct> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <dbl>
1 a 0.942 0.883 0.254 16.1 0.0584 3 2.06 3.89 2.32 0.129
2 b 0.942 0.883 0.254 16.1 0.0584 3 2.06 3.89 2.32 0.129
3 c 0.857 0.714 0.396 6 0.143 3 -0.177 8.35 6.79 0.314
4 d 0.550 0.101 2.03 1.22 0.450 3 -8.34 24.7 23.1 8.23
# ... with 1 more variable: df.residual <int>
您可以使用任何这些度量来定义标准。在我们的例子中,我将使用r.squared,因为它可以衡量拟合的好坏。这是df5中的输出:
# A tibble: 4 x 2
group r.squared
<fct> <dbl>
1 a 0.942
2 b 0.942
3 c 0.857
4 d 0.550
作为数据分析师,我可以将具有良好性能的模型设置为 r.squared 高于 0.9 的模型。所以有了这个定义,我可以使用left_join() 和filter() 构建下一个管道,以便只保留正确拟合的模型:
#Pipeline for plots
df4 %>% left_join(df5) %>%
filter(r.squared>=0.9) %>%
ggplot(aes(x = pop, y = value, color = group)) +
geom_smooth(method='lm', formula = y~poly(x,2), se = FALSE)+
geom_point()
输出:
您可以使用任何统计度量来定义具有良好拟合度的模型,并且您可以在一个函数中设置所有代码以应用于多个数据帧。