含中介、混杂与碰撞器的观测数据集模拟问题求助
需求与问题
DAG结构说明
要模拟包含三类因果结构的数据集:
- 中介关系:X → S → Y
- 混杂关系:X ← C → Y
- 碰撞器结构:X → S ← E
其中S同时作为中介变量和碰撞器。
参考资源
- 之前的Stack Overflow回答
- 观测数据模拟教程
- 碰撞器模拟示例
核心参数
设定的核心效应参数如下(所有效应为正,可调整):
n <- 1000 b_xs <- 5 # X对S的直接效应(x=1时,s增加5,s为计数型变量) b_sy <- 0.05 # S对Y的直接效应(s每增加1单位,y增加0.05) b_xy <- 1.25 # X对Y的直接效应(x=1时,y增加1.25,y取值0-10) # X对Y的间接效应=0.25 b_xs*b_sy # X对Y的总效应=1.5: b_xy + b_xs*b_sy
额外的效应参数:
b_es <- 0.6 # E对S的直接效应(e=1时,s增加0.6) b_ey <- 0.5 # E对Y的直接效应(e=1时,y增加0.5) b_cx <- 0.1 # C对X的直接效应(c=1时,x取1的概率更高) b_cy <- 0.5 # C对Y的直接效应(c=1时,y增加0.5)
基准值生成逻辑
用tabulate()生成Y和S的初始整数值:
# 生成y的基准值(取值0-10,均值4) k <- 10 # 从1到k抽取整数样本 m <- 4 # y的预期基准均值 m_ <- m + 1 # 偏移1,适配sample.int抽取1:10而非0:10的样本 z <- n*m_ # 生成s的基准值(取值1到8,均值4) ks <- 8 # 从1到ks抽取整数样本 ms <- 4 # s的预期基准均值 ms_ <- ms + 1 # 偏移1,适配sample.int抽取1:8而非0:7的样本 zs <- n*ms_
当前实现代码
# 模拟数据集 library(tidyverse) set.seed(21) d <- # 创建外生变量e、c和y的基准值 tibble( e = rbinom(n, size = 1, prob = .5), c = rbinom(n, size = 1, prob = .5), y_base = tabulate(sample.int((k-1)*n, z-n) %% n + 1, n) ) %>% # 基于c生成x mutate( x_score = c + rnorm(n, mean = 0, sd = 1), # 将得分缩放到0.05-0.95作为x的取值概率 x_probability = scales::rescale(x_score, to = c(0.05, 0.95)), # 生成0/1变量x x = rbinom(n, 1, x_probability) ) %>% # 基于x和e生成s mutate( s_effect = (b_xs*x) + (b_es*e), s = s_base + s_effect + rnorm(n, 0, sd = 0.5) ) %>% # 基于x、s、e、c生成y mutate( y_effect = (b_xy*x) + (b_sy*s)/max(s) + (b_ey*e) + (b_cy*c), y = y_base + y_effect + rnorm(n, 0, sd = 1), y = floor(scales::rescale(y, to = c(min(y_base), 10))) ) %>% select(x, y, c, s, e)
当前问题:系数结果不符合预期,比如加入c后x的系数没有变化,希望找到更优/简便的实现方法。
预期模型结果
期望通过以下模型得到对应结论:
tidy(lm(y ~ x, data = d)) # X→Y总效应的朴素估计存在偏差 tidy(lm(y ~ x + c, data = d)) # 控制c后还原X→Y的总效应1.5 tidy(lm(y ~ x + c + s, data = d)) # 加入s会打开X→S←E→Y路径,引入偏差 tidy(lm(y ~ x + c + s + e, data = d)) # 加入s+e得到无偏的X→Y直接效应1.25
疑问
对最终模型lm(y ~ x + c + s + e, data = d)中x的目标结果可能存在误解:认为对s进行条件限制会得到有偏的直接效应估计,而加入e可关闭偏差路径。
内容的提问来源于stack exchange,提问作者Eric Green
相关产品推荐
相关产品推荐

