R语言如何生成满足行约束条件的自引用数据框
问题原因
你原来的写法以前置变量作为正态分布的均值,但正态分布的随机取值有50%概率低于均值,自然会出现大量不满足约束的情况。要保证后续变量严格大于前置变量,我们可以通过截断随机数生成范围的方式实现,以下是两种可行方案:
方案1:使用截断正态分布包(推荐,代码最简洁)
借助truncnorm包直接生成下限为前置变量取值的正态分布随机数,和你最初的生成逻辑匹配度最高:
# 首次使用需要先安装包,已安装可跳过install.packages行 install.packages("truncnorm") library(truncnorm) set.seed(123) # 固定随机种子方便复现结果 var_1 <- rnorm(1000, 8, 5) # a参数指定生成随机数的下限,保证var2严格大于var1 var_2 <- rtruncnorm(n = 1000, a = var_1 + 1e-9, mean = var_1, sd = 5) var_3 <- rnorm(1000, 8, 5) var_4 <- rtruncnorm(n = 1000, a = var_3 + 1e-9, mean = var_3, sd = 5) var_5 <- rnorm(1000, 6, 5) var_6 <- rtruncnorm(n = 1000, a = var_5 + 1e-9, mean = var_5, sd = 5) var_7 <- rtruncnorm(n = 1000, a = var_6 + 1e-9, mean = var_6, sd = 5) frame_b <- data.frame(var_1, var_2, var_3, var_4, var_5, var_6, var_7)
方案2:无额外依赖的拒绝采样实现
如果不想安装第三方包,可以针对不满足约束的行重新生成随机值,直到所有行符合要求,1000行的场景下运行速度极快:
set.seed(123) n <- 1000 var_1 <- rnorm(n, 8, 5) var_2 <- rnorm(n, var_1, 5) # 循环重新生成不满足条件的行 while(any(var_2 <= var_1)){ idx <- which(var_2 <= var_1) var_2[idx] <- rnorm(length(idx), var_1[idx], 5) } var_3 <- rnorm(n, 8, 5) var_4 <- rnorm(n, var_3, 5) while(any(var_4 <= var_3)){ idx <- which(var_4 <= var_3) var_4[idx] <- rnorm(length(idx), var_3[idx], 5) } var_5 <- rnorm(n, 6, 5) var_6 <- rnorm(n, var_5, 5) while(any(var_6 <= var_5)){ idx <- which(var_6 <= var_5) var_6[idx] <- rnorm(length(idx), var_5[idx], 5) } var_7 <- rnorm(n, var_6, 5) while(any(var_7 <= var_6)){ idx <- which(var_7 <= var_6) var_7[idx] <- rnorm(length(idx), var_6[idx], 5) } frame_b <- data.frame(var_1, var_2, var_3, var_4, var_5, var_6, var_7)
约束验证
运行以下代码可确认所有行都满足要求,4个校验语句都会返回TRUE:
all(frame_b$var_2 > frame_b$var_1) all(frame_b$var_4 > frame_b$var_3) all(frame_b$var_6 > frame_b$var_5) all(frame_b$var_7 > frame_b$var_6)
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

