如何在数据框子集上运行GLM并生成新列存储中点值?
分组计算GLM中点的解决方案
没问题,我来帮你搞定这个分组拟合GLM并计算中点的需求。你的原始代码之所以无效,是因为用group_by之后直接调用glm并不会自动按分组处理——glm还是会用整个数据框拟合模型,而不是每个单独的分组。我们可以用dplyr的分组操作函数来实现你的需求,下面分两种场景给出代码:
场景1:给原数据框添加分组中点列
如果你想把每个分组的中点值填充到对应分组的所有行中,可以用mutate结合自定义函数来实现:
首先加载dplyr包(如果没安装先运行install.packages("dplyr")):
library(dplyr)
然后定义一个计算中点的函数,还加入了异常处理(避免某些分组数据不足导致模型拟合失败):
calculate_midpoint <- function(group_data) { # 对当前分组数据拟合GLM glm_fit <- glm(coderesponse ~ stimulus, family = binomial(link = "logit"), data = group_data) # 检查系数是否完整(避免分组数据无法拟合模型的情况) if (length(glm_fit$coefficients) >= 2) { -glm_fit$coefficients[1] / glm_fit$coefficients[2] } else { NA_real_ # 无法拟合时返回NA } }
接下来按分组计算并添加中点列:
# 按subject、stimtype、block分组,给每个分组添加midpoint列 dummy_with_midpoint <- dummy %>% group_by(subject, stimtype, block) %>% mutate(midpoint = calculate_midpoint(cur_data())) %>% ungroup()
这里的cur_data()会获取当前分组的子集数据,确保每个分组单独拟合GLM,计算出的中点会填充到该分组的每一行中。
场景2:生成仅含分组信息和中点的聚合表
如果你只需要每个分组一行的聚合结果(不需要保留原数据的重复行),可以用summarize代替mutate:
# 分组聚合得到每个分组的中点 midpoint_summary <- dummy %>% group_by(subject, stimtype, block) %>% summarize( midpoint = calculate_midpoint(cur_data()), .groups = "drop" # 取消分组,返回普通数据框 )
运行后midpoint_summary里就只有subject、stimtype、block和对应的midpoint四列,每个分组一行数据。
验证结果
你可以打印结果看看是否符合预期:
# 查看带中点的原数据 head(dummy_with_midpoint) # 查看聚合的中点表 print(midpoint_summary)
注意事项
- 如果某些分组的样本量太小,或者
stimulus在分组内没有变化,GLM可能无法拟合出有效系数,这时候函数会返回NA,你可以根据实际数据调整分组逻辑或者处理这些NA值。 - 确保你的数据中每个分组都有足够的
coderesponse的0和1值,否则二项式GLM可能无法收敛。
内容的提问来源于stack exchange,提问作者LizJu
相关产品推荐
相关产品推荐

