如何为NHL轮换数据生成哑变量并构建泊松GAM模型?
解决方案:NHL轮换数据转哑变量并构建GAM泊松模型
我来帮你搞定这个问题——从自动生成球员哑变量到动态构建模型公式,全程用tidyverse和mgcv实现,完美解决你提到的!!和符号拼接的使用需求:
第一步:加载依赖包
首先确保你安装并加载了需要的工具包:
install.packages(c("tidyverse", "mgcv")) library(tidyverse) library(mgcv)
第二步:自动生成球员哑变量
手动创建每个球员的哑变量太繁琐,我们用map_dfc批量处理,不管后续球员数量多少都能自动适配:
# 你的原始轮换数据 data <- tibble( shift_id = c(1, 2, 3, 4, 5, 6, 7, 8,9,10), shift_duration = c(12, 7, 30, 11, 14, 16, 19, 32,11,12), goal_for = c(1, 1, 0, 0, 1, 1, 0, 0,0,0), for_players = list( c("A", "B"), c("A", "C"), c("B", "C"), c("A", "C"), c("B", "C"), c("A", "B"), c("B", "C"), c("A", "B"), c("B", "C"), c("A", "B") ), against_players = list( c("X", "Z"), c("Y", "Z"), c("X", "Y"), c("X", "Y"), c("X", "Z"), c("Y", "Z"), c("X", "Y"), c("Y", "Z"), c("X", "Y"), c("Y", "Z") ) ) # 获取所有己方/对方球员的唯一ID all_for_players <- data$for_players %>% unlist() %>% unique() %>% sort() all_against_players <- data$against_players %>% unlist() %>% unique() %>% sort() # 批量生成己方球员哑变量:1表示该球员在本次轮换在场,0则不在 for_dummies <- map_dfc(all_for_players, function(player) { data$for_players %>% map_int(~as.integer(player %in% .x)) %>% set_names(str_c("for_player_", player)) }) # 批量生成对方球员哑变量 against_dummies <- map_dfc(all_against_players, function(player) { data$against_players %>% map_int(~as.integer(player %in% .x)) %>% set_names(str_c("against_player_", player)) }) # 合并得到最终建模用数据集 model_data <- data %>% select(-for_players, -against_players) %>% bind_cols(for_dummies, against_dummies)
运行这段代码后,你就能得到和示例完全一致的model_data。
第三步:动态构建GAM模型公式(用到!!)
手动写所有球员变量太容易出错,我们用tidyeval语法动态生成公式,完美匹配你的需求:
# 整理所有需要纳入模型的球员变量 model_terms <- c( str_c("for_player_", all_for_players), str_c("against_player_", all_against_players) ) # 用tidyeval构建公式:!!! 用来解包变量列表,把符号直接插入公式 gam_formula <- goal_for ~ offset(log(shift_duration)) + !!!syms(model_terms) # 拟合泊松GAM模型 mod.gam <- mgcv::gam( data = model_data, formula = gam_formula, family = poisson(link = log) )
这里的syms()把字符串转换成R的符号对象,!!!(unquote-splice)则把这些符号直接插入到公式中,实现了完全动态的公式构建。
第四步:查看模型结果
运行以下命令就能得到你示例中的模型输出:
summary(mod.gam)
结果小说明
你会看到部分系数显示为NA,这是因为球员阵容存在完全共线性:比如每次轮换都有2名己方球员在场,三个己方哑变量的和恒为2,模型会自动剔除冗余变量(比如for_player_A和against_player_Y),这是正常现象,mgcv会自动处理这种情况,不需要手动剔除。
内容的提问来源于stack exchange,提问作者Zoltan
相关产品推荐
相关产品推荐

