Simulate data from a general SEM model including non-linear effects and general link and distribution of variables.
Usage
# S3 method for class 'lvm'
sim(x, n = NULL, p = NULL, normal = FALSE, cond = FALSE,
sigma = 1, rho = 0.5, X = NULL, unlink=FALSE, latent=TRUE,
use.labels = TRUE, seed=NULL, ...)Arguments
- x
Model object
- n
Number of simulated values/individuals
- p
Parameter value (optional)
- normal
Logical indicating whether to simulate data from a multivariate normal distribution conditional on exogenous variables hence ignoring functional/distribution definition
- cond
for internal use
- sigma
Default residual variance (1)
- rho
Default covariance parameter (0.5)
- X
Optional matrix of fixed values of variables (manipulation)
- unlink
Return Inverse link transformed data
- latent
Include latent variables (default TRUE)
- use.labels
convert categorical variables to factors before applying transformation
- seed
Random seed
- ...
Additional arguments to be passed to the low level functions
Examples
##################################################
## Logistic regression
##################################################
m <- lvm(y~x+z)
regression(m) <- x~z
distribution(m,~y+z) <- binomial.lvm("logit")
d <- sim(m,1e3)
head(d)
#> y x z
#> 1 1 0.40384929 1
#> 2 0 0.24566058 0
#> 3 0 -1.90110113 0
#> 4 1 0.93173113 0
#> 5 1 -0.01950306 1
#> 6 0 -0.39374796 0
e <- estimate(m,d,estimator="glm")
e
#> Estimate Std. Error Z-value P-value
#> Regressions:
#> y~x 0.97754 0.09021 10.83680 <1e-12
#> y~z 1.10148 0.17286 6.37194 1.866e-10
#> x~z 0.94600 0.06534 14.47800 <1e-12
#> Intercepts:
#> y 0.11229 0.09813 1.14427 0.2525
#> x 0.03084 0.04550 0.67781 0.4979
#> Dispersion:
#> x 1.06937
## Simulate a few observation from estimated model
sim(e,n=5)
#> y x z
#> 1 1 0.8614565 1
#> 2 0 -0.8681925 0
#> 3 0 -0.2137645 1
#> 4 1 2.8122735 1
#> 5 1 1.4170839 1
##################################################
## Poisson
##################################################
distribution(m,~y) <- poisson.lvm()
d <- sim(m,1e4,p=c(y=-1,"y~x"=2,z=1))
head(d)
#> y x z
#> 1 2 0.42357168 1
#> 2 15 1.46385660 1
#> 3 0 -2.37867359 0
#> 4 45 1.77208207 1
#> 5 0 -0.43251382 1
#> 6 0 -0.02905308 0
estimate(m,d,estimator="glm")
#> Estimate Std. Error Z-value P-value
#> Regressions:
#> y~x 2.00130 0.00168 1188.26216 <1e-12
#> y~z 0.98389 0.01204 81.73191 <1e-12
#> x~z 1.03013 0.02254 45.70045 <1e-12
#> Intercepts:
#> y -0.98389 0.01220 -80.66118 <1e-12
#> x -0.02456 0.01925 -1.27584 0.202
#> Dispersion:
#> x 1.00378
mean(d$z); lava:::expit(1)
#> [1] 0.7254
#> [1] 0.7310586
summary(lm(y~x,sim(lvm(y[1:2]~4*x),1e3)))
#>
#> Call:
#> lm(formula = y ~ x, data = sim(lvm(y[1:2] ~ 4 * x), 1000))
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -4.2200 -1.0532 0.0316 0.9507 4.5948
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 0.99506 0.04544 21.90 <2e-16 ***
#> x 4.00185 0.04426 90.41 <2e-16 ***
#> ---
#> Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#>
#> Residual standard error: 1.437 on 998 degrees of freedom
#> Multiple R-squared: 0.8912, Adjusted R-squared: 0.8911
#> F-statistic: 8175 on 1 and 998 DF, p-value: < 2.2e-16
#>
##################################################
### Gamma distribution
##################################################
m <- lvm(y~x)
distribution(m,~y+x) <- list(Gamma.lvm(shape=2),binomial.lvm())
intercept(m,~y) <- 0.5
d <- sim(m,1e4)
summary(g <- glm(y~x,family=Gamma(),data=d))
#>
#> Call:
#> glm(formula = y ~ x, family = Gamma(), data = d)
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 0.507575 0.005117 99.20 <2e-16 ***
#> x 1.002598 0.016261 61.66 <2e-16 ***
#> ---
#> Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#>
#> (Dispersion parameter for Gamma family taken to be 0.5151108)
#>
#> Null deviance: 8368.5 on 9999 degrees of freedom
#> Residual deviance: 5546.7 on 9998 degrees of freedom
#> AIC: 20669
#>
#> Number of Fisher Scoring iterations: 6
#>
if (FALSE) MASS::gamma.shape(g) # \dontrun{}
args(lava::Gamma.lvm)
#> function (link = "inverse", shape, rate, unit = FALSE, var = FALSE,
#> log = FALSE, ...)
#> NULL
distribution(m,~y) <- Gamma.lvm(shape=2,log=TRUE)
sim(m,10,p=c(y=0.5))[,"y"]
#> [1] -1.3148925 0.0231124 0.6164099 -0.3583493 -0.0718344 -0.2697476
#> [7] -1.1070485 1.0313895 0.7453192 -1.1577031
##################################################
### Beta
##################################################
m <- lvm()
distribution(m,~y) <- beta.lvm(alpha=2,beta=1)
var(sim(m,100,"y,y"=2))
#> y
#> y 1.027512
distribution(m,~y) <- beta.lvm(alpha=2,beta=1,scale=FALSE)
var(sim(m,100))
#> y
#> y 0.04661863
##################################################
### Transform
##################################################
m <- lvm()
transform(m,xz~x+z) <- function(x) x[1]*(x[2]>0)
regression(m) <- y~x+z+xz
d <- sim(m,1e3)
summary(lm(y~x+z + x*I(z>0),d))
#>
#> Call:
#> lm(formula = y ~ x + z + x * I(z > 0), data = d)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -3.6128 -0.6418 0.0358 0.6943 3.0594
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) -0.0103490 0.0627031 -0.165 0.869
#> x 1.0236548 0.0452818 22.606 <2e-16 ***
#> z 1.0021651 0.0543581 18.436 <2e-16 ***
#> I(z > 0)TRUE 0.0001651 0.1087734 0.002 0.999
#> x:I(z > 0)TRUE 0.9391138 0.0626959 14.979 <2e-16 ***
#> ---
#> Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#>
#> Residual standard error: 1.011 on 995 degrees of freedom
#> Multiple R-squared: 0.7824, Adjusted R-squared: 0.7815
#> F-statistic: 894.4 on 4 and 995 DF, p-value: < 2.2e-16
#>
##################################################
### Non-random variables
##################################################
m <- lvm()
distribution(m,~x+z+v+w) <- list(Sequence.lvm(0,5),## Seq. 0 to 5 by 1/n
Binary.lvm(), ## Vector of ones
Binary.lvm(0.5), ## 0.5n 0, 0.5n 1
Binary.lvm(interval=list(c(0.3,0.5),c(0.8,1))))
sim(m,10)
#> x z v w
#> 1 0.0000000 1 0 0
#> 2 0.5555556 1 0 0
#> 3 1.1111111 1 0 1
#> 4 1.6666667 1 0 1
#> 5 2.2222222 1 0 1
#> 6 2.7777778 1 1 0
#> 7 3.3333333 1 1 0
#> 8 3.8888889 1 1 1
#> 9 4.4444444 1 1 1
#> 10 5.0000000 1 1 1
##################################################
### Cox model
### piecewise constant hazard
################################################
m <- lvm(t~x)
rates <- c(1,0.5); cuts <- c(0,5)
## Constant rate: 1 in [0,5), 0.5 in [5,Inf)
distribution(m,~t) <- coxExponential.lvm(rate=rates,timecut=cuts)
if (FALSE) { # \dontrun{
d <- sim(m,2e4,p=c("t~x"=0.1)); d$status <- TRUE
plot(timereg::aalen(survival::Surv(t,status)~x,data=d,
resample.iid=0,robust=0),spec=1)
L <- approxfun(c(cuts,max(d$t)),f=1,
cumsum(c(0,rates*diff(c(cuts,max(d$t))))),
method="linear")
curve(L,0,100,add=TRUE,col="blue")
} # }
##################################################
### Cox model
### piecewise constant hazard, gamma frailty
##################################################
m <- lvm(y~x+z)
rates <- c(0.3,0.5); cuts <- c(0,5)
distribution(m,~y+z) <- list(coxExponential.lvm(rate=rates,timecut=cuts),
loggamma.lvm(rate=1,shape=1))
if (FALSE) { # \dontrun{
d <- sim(m,2e4,p=c("y~x"=0,"y~z"=0)); d$status <- TRUE
plot(timereg::aalen(survival::Surv(y,status)~x,data=d,
resample.iid=0,robust=0),spec=1)
L <- approxfun(c(cuts,max(d$y)),f=1,
cumsum(c(0,rates*diff(c(cuts,max(d$y))))),
method="linear")
curve(L,0,100,add=TRUE,col="blue")
} # }
## Equivalent via transform (here with Aalens additive hazard model)
m <- lvm(y~x)
distribution(m,~y) <- aalenExponential.lvm(rate=rates,timecut=cuts)
distribution(m,~z) <- Gamma.lvm(rate=1,shape=1)
transform(m,t~y+z) <- prod
sim(m,10)
#> y x z t
#> 1 -3.2840809 -0.5313786 0.081230892 -0.266768824
#> 2 0.4684835 1.0017989 0.842582853 0.394736176
#> 3 0.1286571 0.7976910 1.952164664 0.251159881
#> 4 3.8958800 0.3282328 2.346598408 9.142065876
#> 5 -0.9036212 -0.4915184 0.087873678 -0.079404519
#> 6 0.1126743 1.0220275 1.532014757 0.172618715
#> 7 0.6427252 0.3751732 0.508685001 0.326944669
#> 8 1.4215918 -0.1591446 0.590513776 0.839469548
#> 9 0.3313485 1.3396558 0.205874305 0.068216143
#> 10 0.3355325 0.1197760 0.009979276 0.003348371
## Shared frailty
m <- lvm(c(t1,t2)~x+z)
rates <- c(1,0.5); cuts <- c(0,5)
distribution(m,~y) <- aalenExponential.lvm(rate=rates,timecut=cuts)
distribution(m,~z) <- loggamma.lvm(rate=1,shape=1)
if (FALSE) { # \dontrun{
mets::fast.reshape(sim(m,100),varying="t")
} # }
##################################################
### General multivariate distributions
##################################################
if (FALSE) { # \dontrun{
m <- lvm()
distribution(m,~y1+y2,oratio=4) <- VGAM::rbiplackcop
ksmooth2(sim(m,1e4),rgl=FALSE,theta=-20,phi=25)
m <- lvm()
distribution(m,~z1+z2,"or1") <- VGAM::rbiplackcop
distribution(m,~y1+y2,"or2") <- VGAM::rbiplackcop
sim(m,10,p=c(or1=0.1,or2=4))
} # }
m <- lvm()
distribution(m,~y1+y2+y3,TRUE) <- function(n,...) rmvn0(n,sigma=diag(3)+1)
var(sim(m,100))
#> y1 y2 y3
#> y1 1.7249852 0.6674309 0.5390163
#> y2 0.6674309 1.4423047 0.7318100
#> y3 0.5390163 0.7318100 1.6936224
## Syntax also useful for univariate generators, e.g.
m <- lvm(y~x+z)
distribution(m,~y,TRUE) <- function(n) rnorm(n,mean=1000)
sim(m,5)
#> y x z
#> 1 994.5267 -2.3053292 -1.8824933
#> 2 998.4568 -1.3360425 -0.3062621
#> 3 1002.8650 -0.3013739 1.0649400
#> 4 1001.3514 1.2848582 0.9951471
#> 5 1000.6749 1.5686740 -0.4457475
distribution(m,~y,"m1",0) <- rnorm
sim(m,5)
#> y x z
#> 1 -0.3940713 -0.6209352 -0.6273853
#> 2 -0.7275340 0.5040422 0.3378076
#> 3 -1.3146335 -1.6480163 0.7666236
#> 4 -1.9969884 -0.9574870 -1.0264748
#> 5 2.5320341 2.2250715 0.4485908
sim(m,5,p=c(m1=100))
#> y x z
#> 1 101.46870 1.6884779 -0.5837411
#> 2 95.68423 -1.1575305 -1.1663874
#> 3 103.15080 0.5007453 1.5080476
#> 4 97.79707 -1.8126868 -0.9694514
#> 5 95.86543 -1.4649504 -0.9732468
##################################################
### Regression design in other parameters
##################################################
## Variance heterogeneity
m <- lvm(y~x)
distribution(m,~y) <- function(n,mean,x) rnorm(n,mean,exp(x)^.5)
if (interactive()) plot(y~x,sim(m,1e3))
## Alternaively, calculate the standard error directly
addvar(m) <- ~sd ## If 'sd' should be part of the resulting data.frame
constrain(m,sd~x) <- function(x) exp(x)^.5
distribution(m,~y) <- function(n,mean,sd) rnorm(n,mean,sd)
if (interactive()) plot(y~x,sim(m,1e3))
## Regression on variance parameter
m <- lvm()
regression(m) <- y~x
regression(m) <- v~x
##distribution(m,~v) <- 0 # No stochastic term
## Alternative:
## regression(m) <- v[NA:0]~x
distribution(m,~y) <- function(n,mean,v) rnorm(n,mean,exp(v)^.5)
if (interactive()) plot(y~x,sim(m,1e3))
## Regression on shape parameter in Weibull model
m <- lvm()
regression(m) <- y ~ z+v
regression(m) <- s ~ exp(0.6*x-0.5*z)
distribution(m,~x+z) <- binomial.lvm()
distribution(m,~cens) <- coxWeibull.lvm(scale=1)
distribution(m,~y) <- coxWeibull.lvm(scale=0.1,shape=~s)
eventTime(m) <- time ~ min(y=1,cens=0)
if (interactive()) {
d <- sim(m,1e3)
require(survival)
(cc <- coxph(Surv(time,status)~v+strata(x,z),data=d))
plot(survfit(cc) ,col=1:4,mark.time=FALSE)
}
##################################################
### Categorical predictor
##################################################
m <- lvm()
## categorical(m,K=3) <- "v"
categorical(m,labels=c("A","B","C")) <- "v"
regression(m,additive=FALSE) <- y~v
if (FALSE) { # \dontrun{
plot(y~v,sim(m,1000,p=c("y~v:2"=3)))
} # }
m <- lvm()
categorical(m,labels=c("A","B","C"),p=c(0.5,0.3)) <- "v"
regression(m,additive=FALSE,beta=c(0,2,-1)) <- y~v
## equivalent to:
## regression(m,y~v,additive=FALSE) <- c(0,2,-1)
regression(m,additive=FALSE,beta=c(0,4,-1)) <- z~v
table(sim(m,1e4)$v)
#>
#> A B C
#> 5001 3050 1949
glm(y~v, data=sim(m,1e4))
#>
#> Call: glm(formula = y ~ v, data = sim(m, 10000))
#>
#> Coefficients:
#> (Intercept) vB vC
#> -0.003607 2.032486 -0.983431
#>
#> Degrees of Freedom: 9999 Total (i.e. Null); 9997 Residual
#> Null Deviance: 22410
#> Residual Deviance: 9816 AIC: 28200
glm(y~v, data=sim(m,1e4,p=c("y~v:1"=3)))
#>
#> Call: glm(formula = y ~ v, data = sim(m, 10000, p = c(`y~v:1` = 3)))
#>
#> Coefficients:
#> (Intercept) vB vC
#> -0.001448 3.033790 -0.987477
#>
#> Degrees of Freedom: 9999 Total (i.e. Null); 9997 Residual
#> Null Deviance: 34140
#> Residual Deviance: 9790 AIC: 28170
transform(m,v2~v) <- function(x) x=='A'
sim(m,10)
#> v y z v2
#> 1 C -1.4228910 -2.3743813 FALSE
#> 2 B 3.7990113 2.3934600 FALSE
#> 3 A 0.7750815 -0.3692173 TRUE
#> 4 C 0.1102358 -0.8214093 FALSE
#> 5 B 1.5153310 6.1654183 FALSE
#> 6 B 2.8497096 5.6700463 FALSE
#> 7 B 2.0529501 4.3634553 FALSE
#> 8 B 2.3471577 3.7715189 FALSE
#> 9 C -2.3345083 -2.2933131 FALSE
#> 10 A 2.1200748 -0.2894096 TRUE
##################################################
### Pre-calculate object
##################################################
m <- lvm(y~x)
m2 <- sim(m,'y~x'=2)
sim(m,10,'y~x'=2)
#> y x
#> 1 4.2044588 2.1870327
#> 2 -1.2835247 -0.3542078
#> 3 -0.6652916 0.1662725
#> 4 4.3367737 0.5560635
#> 5 -2.3096870 -1.3264723
#> 6 1.0442205 0.1227436
#> 7 -2.4180767 -0.5474568
#> 8 0.8563611 1.1660111
#> 9 -0.8626151 -0.9314213
#> 10 4.0543733 1.3070954
sim(m2,10) ## Faster
#> y x
#> 1 1.3121923 1.50961388
#> 2 1.0176849 0.14595064
#> 3 -3.8403860 -1.48995665
#> 4 0.9179312 -0.13233502
#> 5 0.8011242 0.01558654
#> 6 2.1012753 1.01420451
#> 7 -1.4526002 -1.29120883
#> 8 2.1422520 1.23362195
#> 9 2.8050867 0.67871130
#> 10 2.7790760 1.50309619
