繁体   English   中英

生成与现有变量具有预定义相关性的二元变量

[英]Generate a binary variable with a predefined correlation to an already existing variable

对于模拟研究,我想生成一组随机变量(连续变量和二进制变量),这些变量具有与已经存在的二进制变量的预定义关联,此处表示为x

对于这篇文章,假设x是按照下面的代码生成的。 但请记住:在现实生活中, x是一个已经存在的变量。

set.seed(1245)
x <- rbinom(1000, 1, 0.6)

我想生成一个二进制变量和一个连续变量。 我已经想出了如何生成一个连续变量(见下面的代码)

set.seed(1245)

cor <- 0.8 #Correlation 
y <- rnorm(1000, cor*x, sqrt(1-cor^2))

但是我找不到生成与现有变量x相关的二进制变量的方法。 我发现了几个 R 包,例如可以生成具有给定依赖结构的随机变量的copula 但是,它们不提供生成对现有变量具有集合依赖性的变量的可能性。

有谁知道如何以有效的方式做到这一点?

谢谢!

如果我们看一下相关性的公式:

在此处输入图像描述

对于新的向量 y,如果我们保留均值,问题就更容易解决。 这意味着我们复制向量x并尝试翻转相同数量的 1 和 0 以实现预期的相关值。

如果我们让E(X) = E(Y) = x_barE(XY) = xy_bar ,那么对于给定的 rho,我们将上述简化为:

(xy_bar - x_bar^2) / (x_bar - x_bar^2) =  rho

解决,我们得到:

xy_bar = rho * x_bar + (1-rho)*x_bar^2

我们可以推导出一个 function 来翻转多个 1 和 0 得到结果:

create_vector = function(x,rho){

  n = length(x)
  x_bar = mean(x)
  xy_bar = rho * x_bar + (1-rho)*x_bar^2
  toflip = sum(x == 1) - round(n * xy_bar)

  y = x
  y[sample(which(x==0),toflip)] = 1
  y[sample(which(x==1),toflip)] = 0
  return(y)
}

对于您的示例,它有效:

set.seed(1245)
x <- rbinom(1000, 1, 0.6)
cor(x,create_vector(x,0.8))
[1] 0.7986037

有一些预期的 rho 和 p 的极端组合可能会遇到问题,例如:

set.seed(111)

res = lapply(1:1000,function(i){
             
              this_rho = runif(1)
              this_p = runif(1)
              x = rbinom(1000,1,this_p)
              data.frame(
                intended_rho = this_rho,
                p = this_p,
                resulting_cor = cor(x,create_vector(x,this_rho))
              )
           })

res = do.call(rbind,res)

ggplot(res,aes(x=intended_rho,y=resulting_cor,col=p)) + geom_point()

在此处输入图像描述

这是一个二项式 - q的公式仅取决于x的平均值和您想要的相关性。

set.seed(1245)
cor <- 0.8
x <- rbinom(100000, 1, 0.6)
p <- mean(x)
q <- 1/((1-p)/cor^2+p)
y <- rbinom(100000, 1, q)
z <- x*y
cor(x,z)
#> [1] 0.7984781

这不是这样做的唯一方法 - 请注意,在此构造中, mean(z)始终小于mean(x)

连续变量的定义更不明确——你真的不关心它的均值/方差,或者其他关于它的分布吗?

这是另一个简单的版本,它以两种方式翻转变量:

set.seed(1245)
cor <- 0.8
x <- rbinom(100000, 1, 0.6)
p <- mean(x)
q <- (1+cor/sqrt(1-(2*p-1)^2*(1-cor^2)))/2
y <- rbinom(100000, 1, q)
z <- x*y+(1-x)*(1-y)
cor(x,z)
#> [1] 0.8001219
mean(z)
#> [1] 0.57908

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM