列表函数帮助并尝试从 R 中的多元正态混合进行模拟

List function help and trying to simulate from a multivarate normal mixture in R

我正在尝试使用以下设置从两个双变量法线的混合中生成数据:

library(MASS)

 N <- 500 #sample size
 components <- c(1,2)

 mu1 <- c(0,0)
 mu2 <- c(4,4)
 mu <- list(mu1,mu2)
 var1 <- cbind(c(1,0),c(0,1))
 var2 <- cbind(c(.5,-.35),c(-.35,.5))
 var <- list(var1,var2)

 pi <- c(.33,.67) #mixing probabilities

 z <- sample(components,prob=pi,size=N,replace=TRUE)

我尝试了以下但它不起作用:

 y <- mvrnorm(n=N,mu=mu[z],Sigma=var[z]) 

我希望它的工作方式类似于生成单变量法线的混合,例如

 y <- rnorm(n=N,mean=true.mu[z],sd=true.sd[z])

其中 true.mu 和 true.sd 只是每个长度为 2 的向量,指定均值和 sd。为什么这在双变量情况下不起作用?我对处理列表的复杂性还比较陌生。

与此同时,我以两种不同的方式生成数据。作为列表:

 for (i in 1:N) {
 if (z[i]==1){y[[i]] <- mvrnorm(1,mu[[1]],var[[1]])}
 else {y[[i]] <- mvrnorm(1,mu[[2]],var[[2]])}
 }

或作为矩阵:

 for (i in 1:N){
 if (z[i]==1){y <- rbind(y,mvrnorm(1,mu[[1]],var[[1]]))}  
 else {y <- rbind(y,mvrnorm(1,mu[[2]],var[[2]]))}
 }

总而言之,我的问题是:

1) 为什么我的第一个方法(避免 for 循环)不起作用?有什么办法可以用那种方式生成这样的数据吗?

2) 对于我的两个 for 循环方法,一个更好还是更受欢迎?稍后我将尝试为 EM 算法编写代码——可以使用列表还是矩阵 easier/better?

感谢您的帮助!我正试图变得对在 R 中写东西 "nicely" 更敏感 :)

方法 mvrnorm 不像 rnorm 那样被向量化,可能是因为它的向量和矩阵(而不是标量)参数会使这变得困难。不过,您可以使用 mapply

y <- mapply(mvrnorm, n=N, mu=mu, Sigma=var)

关于你的第二个问题:通过累积 rbinds 构建矩阵在 R 中可能非常慢。

相反,您最好使用 y <- matrix(0, 1000, 2) 预分配矩阵,然后使用 y[i,]<-.

填充行