使用lm()与ggplot2绘制y轴取100-y时的凹形对数回归方法咨询
R语言调整y轴为100-y时对数回归模型匹配问题
我需要将y轴数据从百分比y调整为100-y时修改对数回归模型,但暂时找不到正确的实现方法,以下是我使用的测试示例:
m=c(3,1,3,2,4,7,10,2,1,44,11,24,1,3,5,11,7,17,8,10,17,34,31,10,7,3,1,6,4,3,4,7,11,14,6,8,34,80,23,54,2,3,2,1,13,8,10,15,2,15,8,11,8,12,9,18,85) q=c(91,78,72,84,74,76,81,80,70,130,131,136,53,56,57,111,60,80,78,76,84,107,85,76,57,57,45,50,68,61,52,59,60,60,51,63,95,93,85,97,52,39,34,40,70,124,90,68,39,81,50,60,74,70,59,53,98) Age=c(rep("Young",24),rep("Old",33)) df=data.frame(Age,m,q)
原始回归尝试
结合散点图,我分别尝试了线性回归与对数回归:
model_lin_df <- df %>% group_by(Age) %>% do(model = glance(lm(m ~ q,data = .))) %>% unnest(model) > model_lin_df # A tibble: 2 x 13 Age r.squared adj.r.squared sigma statistic p.value df logLik AIC BIC deviance df.residual nobs <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <int> 1 Old 0.370 0.350 16.4 18.2 0.000172 1 -138. 282. 287. 8339. 31 33 2 Young 0.418 0.391 8.97 15.8 0.000646 1 -85.7 177. 181. 1771. 22 24 model_exp_df <- df %>% group_by(Age) %>% do(model = glance(lm(log(m) ~ q,data = .))) %>% unnest(model) model_exp_df # A tibble: 2 x 13 Age r.squared adj.r.squared sigma statistic p.value df logLik AIC BIC deviance df.residual nobs <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <int> 1 Old 0.517 0.502 0.776 33.2 0.00000242 1 -37.4 80.8 85.3 18.7 31 33 2 Young 0.362 0.333 0.916 12.5 0.00187 1 -30.9 67.8 71.4 18.5 22 24
并绘制了对应的拟合线:
model_lin <- lm(m ~ Age/q + 0, df,na.action=na.exclude) model_exp <- lm(log(m) ~ Age/q + 0, df,na.action=na.exclude) df_plot <- ggplot(df, aes(x = q, y = m, shape=Age, color=Age)) + geom_point() + geom_line(aes(y = ifelse(Age == "Young", fitted(model_lin), NA))) + geom_line(aes(y = ifelse(Age == "Old", exp(fitted(model_exp)), NA))) + theme_bw() + theme(panel.grid = element_blank())
原始拟合结果图:
y轴调整后的问题
但实际业务中我需要将y轴设置为100-y,对数据表意更合理,我目前无法绘制对数回归的「反转」凹形版本:
s=100-m df=cbind(df,s)
拟合模型的结果显示我需要调整公式:
> model_lin_df2 <- df %>% group_by(Age) %>% do(model = glance(lm(s ~ q,data = .))) %>% unnest(model) > model_lin_df2 # A tibble: 2 x 13 Age r.squared adj.r.squared sigma statistic p.value df logLik AIC BIC deviance df.residual nobs <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <int> 1 Old 0.370 0.350 16.4 18.2 0.000172 1 -138. 282. 287. 8339. 31 33 2 Young 0.418 0.391 8.97 15.8 0.000646 1 -85.7 177. 181. 1771. 22 24 > model_exp_df2 <- df %>% group_by(Age) %>% do(model = glance(lm(log(s) ~ q,data = .))) %>% unnest(model) > model_exp_df2 # A tibble: 2 x 13 Age r.squared adj.r.squared sigma statistic p.value df logLik AIC BIC deviance df.residual nobs <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <int> 1 Old 0.286 0.263 0.363 12.4 0.00134 1 -12.3 30.7 35.2 4.08 31 33 2 Young 0.408 0.381 0.115 15.1 0.000788 1 18.9 -31.8 -28.3 0.291 22 24
线性模型的统计指标和预期一致没有变化(仅曲线为负向),但对数模型的指标出现了差异。我尝试过拟合指数模型lm(exp(s) ~ q,也试过添加负号的"-exp()"写法,但都无法让R²等指标与原log(m) ~ q模型匹配,还试过1/log等其他写法,也找不到适合「Old」分组的模型写法与曲线绘制方法。下图是我当前用log(s)拟合得到的结果:
model_lin2 <- lm(s ~ Age/q + 0, df,na.action=na.exclude) model_exp2 <- lm(log(s) ~ Age/q + 0, df,na.action=na.exclude) df_plot2 <- ggplot(df, aes(x = q, y = s, shape=Age, color=Age)) + geom_point() + geom_line(aes(y = ifelse(Age == "Young", fitted(model_lin2), NA))) + geom_line(aes(y = ifelse(Age == "Old", exp(fitted(model_exp2)), NA))) + theme_bw() + theme(panel.grid = element_blank())
修改y轴后的拟合结果图:
需求
希望能得到可行的解决方法,我认为和线性回归的逻辑一致,100-y版本的对数回归的r²、p值等统计指标应该和原始模型保持一致。
内容的提问来源于stack exchange,提问作者Mata
相关产品推荐
相关产品推荐

