在R中生成离散数据抽样分布:强负phi系数2×2数据模拟报错求助
解决GenOrd生成负phi系数2×2数据的报错问题
嘿,我一眼就看到你代码里的核心问题了:GenOrd的Sigma参数要的是潜在连续正态变量的相关矩阵,不是你最终想要的分类变量的phi(Pearson)相关系数。你直接把目标phi系数(-0.71)塞进去,这肯定会报错——因为潜在变量的相关系数和观测到的分类变量相关系数之间有个转换关系,不是直接划等号的。
怎么修正呢?按这几步来:
- 把目标phi系数转换成潜在正态变量的相关系数:对于两个边际概率都是0.5的二分变量,我们得先把想要的phi系数转成潜在变量的相关系数才行。
- 验证转换后的系数是否可行:用
corrcheck函数确认一下,避免因为系数超出可行范围再报错。 - 生成符合要求的样本
修正后的完整代码:
library(GenOrd) library(mvtnorm) # 需要这个包计算二元正态联合概率 # 指定样本量 N <- 40 # 两个二分变量的边际分布(各自取第一个类别的概率是0.5) marginal <- list(c(0.5), c(0.5)) # 你想要的目标phi系数 target_phi <- -0.71 # 步骤1:将目标phi转换为潜在正态变量的相关系数rho # 先计算边际对应的正态分位数 z1 <- qnorm(marginal[[1]]) z2 <- qnorm(marginal[[2]]) # 定义函数:输入rho,输出观测相关系数与目标phi的差值 rho_to_r_diff <- function(rho) { # 计算二元正态分布下的联合概率 joint_prob <- pmvnorm(lower = c(-Inf, -Inf), upper = c(z1, z2), mean = c(0, 0), sigma = matrix(c(1, rho, rho, 1), nrow = 2))[1] # 计算对应的观测相关系数(phi) observed_r <- (joint_prob - marginal[[1]]*marginal[[2]]) / sqrt(marginal[[1]]*(1-marginal[[1]])*marginal[[2]]*(1-marginal[[2]])) # 返回差值,方便用uniroot求解 return(observed_r - target_phi) } # 求解对应的rho rho_solution <- uniroot(rho_to_r_diff, interval = c(-1, 1))$root # 步骤2:验证这个rho是否在可行范围内 corrcheck(marginal, matrix(c(1, rho_solution, rho_solution, 1), nrow = 2)) # 步骤3:生成样本 m <- ordsample(N, marginal, matrix(c(1, rho_solution, rho_solution, 1), nrow = 2)) # 验证结果:看看生成数据的phi系数是不是接近目标值 print(table(m)) actual_phi <- cor(m)[1, 2] cat("生成数据的实际phi系数:", round(actual_phi, 3), "\n")
为啥之前会报错?
如果你的报错是Error in ordsample(N, marginal, Sigma) : The correlation matrix is not feasible for the given margins.,那完全是因为你直接把观测层面的phi系数当成了潜在变量的相关系数,这个值超出了该边际分布下的可行范围。上面的代码通过转换得到了正确的潜在相关系数,就能顺利生成样本了。
另外提一句:对于两个边际都是0.5的二分变量,phi系数和潜在相关系数数值比较接近,但不是完全相等的——比如你要的phi=-0.71,转换后的rho大概在-0.8左右,运行代码就能看到具体数值啦。
内容的提问来源于stack exchange,提问作者Peter Miksza
相关产品推荐
相关产品推荐

