[英]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_bar
和E(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.