如何在Stata/R中拟合含多水平自变量的多项Logistic回归模型
交通方式选择预测的模型推荐与宽转长数据处理代码
一、适配模型推荐
针对交通方式选择预测需求(嵌套区级多水平变量+备选方案属性缺失),推荐以下模型及处理策略:
1. 多水平混合Logit模型
- 核心优势:
- 完美适配离散选择场景(用户从多个交通方式中选其一);
- 支持嵌套的多水平结构,可纳入区级
Income、Education作为组水平变量,捕捉区域层面的异质性; - 允许个体层面的偏好差异,比传统Multinomial Logit模型的灵活性更强。
- 缺失值处理:
未选择方式的Price/Distance缺失,可先通过同区域同交通方式的均值填充,或采用多重插补(结合District、Income等变量)补充缺失属性,再代入模型。Stata可使用mi命令,R可使用mice包实现多重插补。
2. 条件Logit模型(基础版)
若暂不考虑多水平异质性,条件Logit是最基础的离散选择分析模型,核心用备选方案特异性变量(Price、Distance)和个体社会经济变量(Income、Education)预测选择概率,适合初步探索性分析。
二、宽格式转长格式代码
Stata代码
* 读取宽格式数据 use "Trips_Districts.dta", clear * 为每条行程分配唯一用户ID(每条记录对应一个用户的一次选择) gen Person_id = _n * 定义所有备选交通方式 local modes "Car Train Bus Plane" * 扩展数据:每个用户对应4种交通方式的行 expand 4 bysort Person_id: gen Mode_alt = word("`modes'", _n) * 生成选择标记变量:选中的方式为1,未选中为0 gen Choice = (Mode == Mode_alt) * 将选中方式的Price/Distance复制到对应行,其他行暂为缺失 bysort Person_id: replace Price = Price[1] if Mode_alt == Mode[1] bysort Person_id: replace Distance = Distance[1] if Mode_alt == Mode[1] * 用同区域同交通方式的均值填充缺失的Price/Distance bysort District Mode_alt: egen Price_mean = mean(Price) replace Price = Price_mean if missing(Price) bysort District Mode_alt: egen Distance_mean = mean(Distance) replace Distance = Distance_mean if missing(Distance) * 整理变量并保存 drop Mode Mode_id rename Mode_alt Mode save "Trips_Districts_Final.dta", replace
R代码(基于tidyverse)
library(tidyverse) library(haven) # 读取宽格式数据 trips_wide <- read_dta("Trips_Districts.dta") %>% mutate(Person_id = row_number()) # 生成唯一用户ID # 定义所有备选交通方式 modes <- c("Car", "Train", "Bus", "Plane") # 宽转长并处理缺失值 trips_long <- trips_wide %>% # 每个用户扩展为4行,对应所有备选方式 crossing(Mode_alt = modes) %>% # 生成选择标记变量 mutate(Choice = ifelse(Mode == Mode_alt, 1, 0)) %>% # 复制选中方式的Price/Distance,未选中行设为缺失 group_by(Person_id) %>% mutate( Price = ifelse(Mode_alt == Mode, Price, NA), Distance = ifelse(Mode_alt == Mode, Distance, NA) ) %>% ungroup() %>% # 用同区域同交通方式的均值填充缺失值 group_by(District, Mode_alt) %>% mutate( Price = ifelse(is.na(Price), mean(Price, na.rm = TRUE), Price), Distance = ifelse(is.na(Distance), mean(Distance, na.rm = TRUE), Distance) ) %>% ungroup() %>% # 整理变量 select(-Mode, -Mode_id) %>% rename(Mode = Mode_alt) # 保存长格式数据 write_dta(trips_long, "Trips_Districts_Final.dta")
内容的提问来源于stack exchange,提问作者Sorath Abbasi
相关产品推荐
相关产品推荐

