I want to generate 400 compositional data which meet conditions and then combine them together. The means and variance correlations between three variables used to generate the data are:
mu <- c(45.2, 15.4, 15.4) # means
names (mu) <- c("P", "S", "Fa") # names of the three variances
sted <- c(4.830935, 3.222764, 3.222764) # standard deviations
names (sted) <- c("P", "S", "Fa") # names of the three variances
# covariance matrix:
corMat <- matrix (c(23.337931, -7.737931, -7.737931,
-7.737931, 10.386207, -5.131034,
-7.737931, -5.131034, 10.386207),
ncol = 3, byrow = T)
dimnames (corMat) <- list (row_names = c("P", "S", "Fa"),
col_names = c("P", "S", "Fa"))
The procedure of stimulated data generating includes two steps, as follows:
Step 1: generate a datum with a normal distribution based mean and variance correlations between three variables:
set.seed(1)
library(MASS)
dat1 <- mvrnorm(n = 1, mu = mu, Sigma = corMat, empirical = F)
Step 2: check if dat1
has: P
within the range of 45 <= P <= 55
; S
within 12 <= S <= 22
; and Fa
within 12 <= S <= 22
. If dat1
meets the three conditions of P
, S
and Fa
, accept dat1
.
Repeat steps 1 and 2 until achieving 400
accepted data and rbind
them together.
I found some questions related to repeat break
such as this, but I am still stuck in repeating steps 1 and 2 till obtaining 400
data and bind the data together. Please can anyone help? Thank you very much.
CodePudding user response:
The following solves your problem. However, the generated dat1
appears to never fulfill the conditions you want to impose. Should not dat1
be divided by 100?
nSets <- 0
data <- matrix(ncol=3)
while (nSets < 400)
{
dat1 <- mvrnorm(n = 1, mu = mu, Sigma = corMat, empirical = F)
# dat1 <- dat1/100 <-- maybe this is necessary?
if (dat1["P"] >= 0.45 & dat1["P"] <= 0.55 &
dat1["S"] >= 0.12 & dat1["S"] <= 0.22 &
dat1["Fa"] >= 0.12 & dat1["Fa"] <= 0.22)
{
nSets <- nSets 1
data <- rbind(data,dat1)
}
}
data <- data[-1,]