Skip to content

Commit ec7b9f1

Browse files
committed
lav_mvrnorm: byrow = FALSE (for now), but TRUE in lav_simulate.R
1 parent 363fe73 commit ec7b9f1

File tree

3 files changed

+41
-31
lines changed

3 files changed

+41
-31
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: lavaan
22
Title: Latent Variable Analysis
3-
Version: 0.6-22.2494
3+
Version: 0.6-22.2499
44
Authors@R: c(person(given = "Yves", family = "Rosseel",
55
role = c("aut", "cre"),
66
email = "Yves.Rosseel@UGent.be",

R/lav_simulate.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ lav_data_simulate <- function(model = NULL,
170170
tmp <- try(
171171
lav_mvrnorm(
172172
n = sample.nobs[b],
173-
mu = MU, Sigma = COV, empirical = empirical
173+
mu = MU, Sigma = COV, empirical = empirical, byrow = TRUE
174174
),
175175
silent = TRUE
176176
)

R/lav_utils.R

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@
1616
# eigen is the default to match MASS::mvrnorm's approach while fixing the
1717
# sign-flip issue with the invariant formula
1818
lav_mvrnorm <- function(n = 1, mu, Sigma, tol = 1e-06, empirical = FALSE,
19-
method = "eigen", checkSymmetry = TRUE) {
19+
method = "eigen", checkSymmetry = TRUE, byrow = FALSE) {
2020
p <- length(mu)
2121

2222
# check symmetry (like mvtnorm)
23-
if (checkSymmetry && !isSymmetric(Sigma, tol = sqrt(.Machine$double.eps),
24-
check.attributes = FALSE)) {
23+
if (checkSymmetry && !isSymmetric(Sigma,
24+
tol = sqrt(.Machine$double.eps),
25+
check.attributes = FALSE
26+
)) {
2527
lav_msg_stop(gettext("'Sigma' must be a symmetric matrix in lav_mvrnorm"))
2628
}
2729

@@ -59,10 +61,10 @@ lav_mvrnorm <- function(n = 1, mu, Sigma, tol = 1e-06, empirical = FALSE,
5961

6062
if (empirical) {
6163
# generate standard normal, then apply empirical transformation
62-
X <- matrix(stats::rnorm(p * n), n, p, byrow=TRUE)
63-
X <- scale(X, center = TRUE, scale = FALSE) # center
64-
X <- X %*% svd(X, nu = 0)$v # orthogonalize
65-
X <- scale(X, center = FALSE, scale = TRUE) # unit variance
64+
X <- matrix(stats::rnorm(p * n), n, p, byrow = byrow)
65+
X <- scale(X, center = TRUE, scale = FALSE) # center
66+
X <- X %*% svd(X, nu = 0)$v # orthogonalize
67+
X <- scale(X, center = FALSE, scale = TRUE) # unit variance
6668

6769
# transform by R
6870
X <- sweep(X %*% R, 2, mu, "+")
@@ -71,7 +73,7 @@ lav_mvrnorm <- function(n = 1, mu, Sigma, tol = 1e-06, empirical = FALSE,
7173
if (n == 1) drop(X) else X
7274
} else {
7375
# generate samples (following mvtnorm exactly)
74-
X <- matrix(stats::rnorm(n * p), nrow = n, byrow=TRUE) %*% R
76+
X <- matrix(stats::rnorm(n * p), nrow = n, byrow = byrow) %*% R
7577
X <- sweep(X, 2, mu, "+")
7678
colnames(X) <- nm
7779

@@ -81,46 +83,52 @@ lav_mvrnorm <- function(n = 1, mu, Sigma, tol = 1e-06, empirical = FALSE,
8183

8284
# outlier detection based on inter-quartile range
8385
# same as boxplot.stats, but returning the indices (not the values)
84-
lav_sample_outlier_idx <- function (x, coef = 1.5) {
85-
if (coef < 0)
86-
lav_msg_stop(gettext("'coef' must not be negative"))
86+
lav_sample_outlier_idx <- function(x, coef = 1.5) {
87+
if (coef < 0) {
88+
lav_msg_stop(gettext("'coef' must not be negative"))
89+
}
8790
stats <- stats::fivenum(x, na.rm = TRUE)
8891
iqr <- diff(stats[c(2, 4)])
89-
if (coef == 0)
92+
if (coef == 0) {
9093
return(seq_len(length(x)))
91-
else {
94+
} else {
9295
out <- if (!is.na(iqr)) {
9396
which(x < (stats[2L] - coef * iqr) | x > (stats[4L] + coef * iqr))
97+
} else {
98+
which(!is.finite(x))
9499
}
95-
else which(!is.finite(x))
96100
}
97101
out
98102
}
99103

100104
# sd with trimming
101105
lav_sample_trimmed_sd <- function(x, na.rm = TRUE, trim = 0) {
102-
if (isTRUE(na.rm))
106+
if (isTRUE(na.rm)) {
103107
x <- x[!is.na(x)]
108+
}
104109
n <- length(x)
105110
if (trim > 0 && n) {
106-
if (is.complex(x))
107-
lav_msg_stop(gettext("trimmed means are not defined for complex data"))
108-
if (anyNA(x))
109-
return(NA_real_)
110-
if (trim >= 0.5)
111-
return(stats::median(x, na.rm = FALSE))
112-
lo <- floor(n * trim) + 1
113-
hi <- n + 1 - lo
114-
x <- sort.int(x, partial = unique(c(lo, hi)))[lo:hi]
111+
if (is.complex(x)) {
112+
lav_msg_stop(gettext("trimmed means are not defined for complex data"))
113+
}
114+
if (anyNA(x)) {
115+
return(NA_real_)
116+
}
117+
if (trim >= 0.5) {
118+
return(stats::median(x, na.rm = FALSE))
119+
}
120+
lo <- floor(n * trim) + 1
121+
hi <- n + 1 - lo
122+
x <- sort.int(x, partial = unique(c(lo, hi)))[lo:hi]
115123
}
116124
sd(x)
117125
}
118126

119127
# mdist = Mahalanobis distance
120128
lav_sample_mdist <- function(Y, Mp = NULL, wt = NULL,
121-
Mu = NULL, Sigma = NULL,
122-
Sinv.method = "eigen", ginv = TRUE,
123-
rescale = FALSE) {
129+
Mu = NULL, Sigma = NULL,
130+
Sinv.method = "eigen", ginv = TRUE,
131+
rescale = FALSE) {
124132
# check input
125133
Y <- as.matrix(Y)
126134
P <- NCOL(Y)
@@ -188,7 +196,8 @@ lav_sample_mdist <- function(Y, Mp = NULL, wt = NULL,
188196
)
189197
if (inherits(Sigma.inv, "try-error")) {
190198
lav_msg_warn(gettext(
191-
"problem computing distances: could not invert Sigma"))
199+
"problem computing distances: could not invert Sigma"
200+
))
192201
return(DIST)
193202
}
194203
}
@@ -256,7 +265,8 @@ lav_cor2cov <- function(R, sds, names = NULL) {
256265

257266
if (any(!is.finite(sds))) {
258267
lav_msg_warn(gettext(
259-
"sds had 0 or NA entries; non-finite result is doubtful"))
268+
"sds had 0 or NA entries; non-finite result is doubtful"
269+
))
260270
}
261271

262272
# if(sum(diag(R)) != p)

0 commit comments

Comments
 (0)