-
Generar dos muestras de datos correlacionados de una normal estándar distribución aleatoria siguiendo una determinada correlación.
Como ejemplo, vamos a elegir una correlación de r = 0.7, y el código de una matriz de correlación, tales como:
(C <- matrix(c(1,0.7,0.7,1), nrow = 2))
[,1] [,2]
[1,] 1.0 0.7
[2,] 0.7 1.0
Podemos usar mvtnorm
a generar ahora estas dos muestras como un bivariante vector aleatorio:
set.seed(0)
SN <- rmvnorm(mean = c(0,0), sig = C, n = 1e5)
resultante de dos vectores componentes distribuidos como ~ $N(0, 1)$ y con un cor(SN[,1],SN[,2])= 0.6996197 ~ 0.7
. Ambos componentes pueden ser llevadas de la siguiente manera:
X1 <- SN[,1]; X2 <- SN[,2]
Aquí está la parcela con la superposición de la línea de regresión:
-
El uso de la Probabilidad de Transformación Integral aquí para obtener una bivariante vector aleatorio con distribuciones marginales ~ $U(0, 1)$ e la misma correlación:
U <- pnorm(SN)
- por lo que estamos en la alimentación de pnorm
el SN
vector para encontrar $erf(SN)$ (o $\Phi(SN)$). En el proceso, podemos preservar la cor(U[,1], U[,2]) = 0.6816123 ~ 0.7
.
De nuevo podemos descomponer el vector U1 <- U[,1]; U2 <- U[,2]
y generar un diagrama de dispersión con distribuciones marginales en los bordes, mostrando claramente su uniforme de la naturaleza:
-
Aplicar la inversa de la transformación método de muestreo aquí para obtener finalmente la bivector de igual correlaciona los puntos pertenecientes a cualquiera de distribución de la familia nos dispusimos a reproducir.
A partir de aquí podemos generar dos vectores distribuyen normalmente y con iguales o diferentes variaciones. Por ejemplo: Y1 <- qnorm(U1, mean = 8,sd = 10)
y Y2 <- qnorm(U2, mean = -5, sd = 4)
, que se mantendrá el deseado de correlación, cor(Y1,Y2) = 0.6996197 ~ 0.7
.
O bien optar por diferentes distribuciones. Si las distribuciones elegidas son muy diferentes, la correlación puede no ser tan precisa. Por ejemplo, veamos U1
seguir $t$ distribución con 3 d.f., y U2
una exponencial con un $\lambda$=1: Z1 <- qt(U1, df = 3)
y Z2 <- qexp(U2, rate = 1)
El cor(Z1,Z2) [1] 0.5941299 < 0.7
. Aquí están los respectivos histogramas:
Aquí es un ejemplo de código para el proceso completo y normal marginales:
Cor_samples <- function(r, n, mean1, mean2, sd1, sd2){
C <- matrix(c(1,r,r,1), nrow = 2)
require(mvtnorm)
SN <- rmvnorm(mean = c(0,0), sig = C, n = n)
U <- pnorm(SN)
U1 <- U[,1]
U2 <- U[,2]
Y1 <<- qnorm(U1, mean = mean1,sd = sd1)
Y2 <<- qnorm(U2, mean = mean2,sd = sd2)
sample_measures <<- as.data.frame(c(mean(Y1), mean(Y2), sd(Y1), sd(Y2), cor(Y1,Y2)), names<-c("mean Y1", "mean Y2", "SD Y1", "SD Y2", "Cor(Y1,Y2)"))
sample_measures
}
Para la comparación, he reunido una función que se basa en la descomposición de Cholesky:
Cholesky_samples <- function(r, n, mean1, mean2, sd1, sd2){
C <- matrix(c(1,r,r,1), nrow = 2)
L <- chol(C)
X1 <- rnorm(n)
X2 <- rnorm(n)
X <- rbind(X1,X2)
Y <- t(L)%*%X
Y1 <- Y[1,]
Y2 <- Y[2,]
N_1 <<- Y[1,] * sd1 + mean1
N_2 <<- Y[2,] * sd2 + mean2
sample_measures <<- as.data.frame(c(mean(N_1), mean(N_2), sd(N_1), sd(N_2), cor(N_1, N_2)),
names<-c("mean N_1", "mean N_2", "SD N_1", "SD N_2","cor(N_1,N_2)"))
sample_measures
}
Tratando de ambos métodos para generar correlacionados (por ejemplo, $r=0.7$) muestras distribuidas ~ $N(97,23)$ $N(32,8)$ somos, estableciendo set.seed(99)
:
Usando el Uniforme:
cor_samples(0.7, 1000, 97, 32, 23, 8)
c(mean(Y1), mean(Y2), sd(Y1), sd(Y2), cor(Y1, Y2))
mean Y1 96.5298821
mean Y2 32.1548306
SD Y1 22.8669448
SD Y2 8.1150780
cor(Y1,Y2) 0.7061308
y el Uso de la Cholesky:
Cholesky_samples(0.7, 1000, 97, 32, 23, 8)
c(mean(N_1), mean(N_2), sd(N_1), sd(N_2), cor(N_1, N_2))
mean N_1 96.4457504
mean N_2 31.9979675
SD N_1 23.5255419
SD N_2 8.1459100
cor(N_1,N_2) 0.7282176