Wednesday, October 18, 2017

latent change score model in R


For those interested... I made R implement LCS, it's actually pretty flexible... enjoy!

#as with Mplus code, I suggest you rename your T1 and T2 variables obsY1 and obsY2 first
install.packages("lavaan") #you need to install lavaan first
library(lavaan) #you need to call in lavaan first
#in lavaan the model and data are 2 entities, I like this, they become connected after defining the model

#first the model
LCS2waves <- ' LatY1 =~ 1*obsY1 #define latents behind the observed
obsY1~~ measerr*obsY1 # same measurement error measerr across time
obsY1~0*1 #intercept of 1-indicator@0 to identify the mean of the latent; if free obsY1~1
LatY2 =~ 1*obsY2; #define latents behind the observed
obsY2~~ measerr*obsY2 #same measurement error measerr across time
obsY2~0*1  #intercept of 1-indicator@0 to identify the mean of the latent; if free obsY1~1
#LCS part
LCS21 =~ 1*obsY2 #define LCS on the second variable in subtraction
LatY2 =~ 1*LatY1; # autoregression AR1 @1
LatY2~~0*LatY2 #all LatY2 variance is explained, no error left
LatY1~1 # LatY1 mean of first estimated
LatY2~0*1 # LatY2 intercept =0 so LCS21 mean can be identified
#LCS21~~0*LCS21 #no need to set it to 0 per se, but this commonly becomes <0
LCS21~1 # LCS21 mean or intercept estimated
#this is the mean of change, IF nothing points to it, if anything points to it, need to center them to interpret this intercept
LCS21~LatY1 #proportional growth, this is not needed, if you take it out you will have a covariance between them estimated
'


#now one can fit the model above to some (any) data
fit <- sem(model = LCS2waves, data = YOURDATA)

# show results
summary(fit, fit.measures=TRUE)

#mine showed something like:

lavaan (0.5-23.1097) converged normally after  46 iterations

  Number of observations                            61

  Estimator                                         ML
  Minimum Function Test Statistic                   NA
  Degrees of freedom                                -1
  Minimum Function Value               0.0000000000000

User model versus baseline model:

  Comparative Fit Index (CFI)                       NA
  Tucker-Lewis Index (TLI)                          NA

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)               -409.528
  Loglikelihood unrestricted model (H1)       -409.528

  Number of free parameters                          6
  Akaike (AIC)                                 831.056
  Bayesian (BIC)                               843.721
  Sample-size adjusted Bayesian (BIC)          824.846

Root Mean Square Error of Approximation:

  RMSEA                                             NA
  90 Percent Confidence Interval             NA     NA
  P-value RMSEA <= 0.05                             NA

Standardized Root Mean Square Residual:

  SRMR                                           0.000

Parameter Estimates:

  Information                                 Expected
  Standard Errors                             Standard

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)
  LatY1 =~                                            
    obsY1             1.000                           
  LatY2 =~                                            
    obsY2             1.000                           
  LCS21 =~                                            
    obsY2             1.000                           
  LatY2 =~                                            
    LatY1             1.000                           

Regressions:
                   Estimate  Std.Err  z-value  P(>|z|)
  LCS21 ~                                             
    LatY1             0.568    0.423    1.341    0.180

Intercepts:
                   Estimate  Std.Err  z-value  P(>|z|)
   .obsY1             0.000                           
   .obsY2             0.000                           
    LatY1             9.131    0.912   10.009    0.000
    LatY2             0.000                           
   .LCS21             3.569    3.742    0.954    0.340

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)
   .obsY1   (msrr)   51.146   14.017    3.649    0.000
   .obsY2   (msrr)   51.146   14.017    3.649    0.000
    LatY2             0.000                           
    LatY1            -0.376   10.659   -0.035    0.972
   .LCS21            -5.233   14.091   -0.371    0.710
 
~~~~~~~~~~~~~~~~~~~~~~~~
This paper introduces LCS amazingly simply and intuitively, a graphical depiction below; when it's going to be published maybe the R code will accompany it. 
 
Berggren, R., Nilsson, J., Brehmer, Y., Schmiedek, F., & Lövdén, M. (2018). No evidence that foreign language learning in older age improve cognitive ability A RCT. 
 

Tuesday, February 14, 2017

A simple DAG

According to a discussion on SEMNET, the model below 'lacks any testable implications' or one 'cannot detect any testable implications', URL.

I like to 'see' things before deciding, so I submitted it to daggityR, simple task in fact, see code below, but 1st the visual ('plot', called in R), and its 'implications' (called 'impliedConditionalIndependencies' in R); this happens to be the simplest' mediation (called Barron-Kenny, BK, see Frontiers commentary for clarifications).
impliedConditionalIndependencies(NoImplic)

M _||_ UX | X
M _||_ UY
UM _||_ UX
UM _||_ UY
UM _||_ X
UM _||_ Y | M, X
UX _||_ UY
UX _||_ Y | X
UY _||_ X

adjustmentSets( NoImplic, "X", "Y", type="all" )

 {}
 { UM }
 { UX }
 { UM, UX }
 { UY }
 { UM, UY }
 { UX, UY }
 { UM, UX, UY }

adjustmentSets( NoImplic, "M", "Y", type="all" )

 { X }
 { UM, X }
 { UX, X }
 { UM, UX, X }
 { UY, X }
 { UM, UY, X }
 { UX, UY, X }
 { UM, UX, UY, X }

# how to build it:
library(dagitty)

NoImplic <- dagitty('dag {
UX [pos="0,1"]
X [pos="1,1"]
UM [pos="1,0"]
M [pos="2,0"]
UY [pos="2.5,1.5"]
Y [pos="3,1"]
UX-> X -> M ->Y <- X
UM -> M
UY -> Y
}')
plot(NoImplic)

~~~~~~~~
Coman, E. N., F. Thoemmes and J. Fifield (2017). Commentary: Causal Effects in Mediation Modeling: An Introduction with Applications to Latent Variables. Frontiers in Psychology 8(151). http://journal.frontiersin.org/article/10.3389/fpsyg.2017.00151/full

Monday, February 6, 2017

DAGs-simple

A recent paper (Fischer,  Dietz, & Antonakis, 2017) proposed a 'specious mediation' model, which is one combination of causal effects flowing in a peculiar pattern; the 'causal story' is told like:
"As an example, perceived justice has been found to mediate the impact of monitoring methods on organizational citizenship behavior (Niehoff & Moorman, 1993). An alternative mediator is trust in the supervisor (Pillai, Schriesheim, & Williams, 1999), which is likely also affected by monitoring and related to perceived justice. Then, if trust but not justice perceptions affected organizational citizenship behaviors, justice perceptions would appear as a significant mediator if trust is not included in the model. Findings from the model excluding trust are not interpretable, because the effect of trust on the parameter estimate for perceived justice is unknown: Perceived justice might be a mediator, although likely with less of an impact than what the estimate suggests, or worse, it might be a specious mediator.
Such a specious mediator can be uncovered only by including true and correlated mediators,such as trust in the model. Given that a cause such as monitoring might have a multitude of proximal effects that are also correlated with trust and perceived justice and that have an effect on organizational citizenship behavior, the risk of ignoring relevant mediators and detecting specious mediators is highly prevalent." [p. 15-16]

Hope I captured it well... One can inspect such DAGs formally, and easily, with daggityR, see code below, see then what it can tell us beyond the informal analysis above.

Here's the original figure, and the R generated one (I took the liberty of labeling in Fig. 4 the variable names from the example, hope they match, although some statements above make me pause, like "perceived justice has been found to mediate the impact of monitoring methods on organizational citizenship behavior", so this is (and then not) a mediator, plus " trust in the supervisor [..is.]  related to perceived justice.", yet the figure says they appear 'related' only because of common cause 'Omitted').



#if daggity is not installed, there, you need to install it
install.packages("dagitty")

#this line below calls the daggity module up
library(dagitty)


# Fischer '17 specious mediation
# the 1st 6 lines simply position variables in a bi-dimensional Y(X) space, you can move them around
#I positioned Omitted to the left of 'mediators' because it is a cause of them

SpeciousF <- dagitty('dag {
Monitoring [pos="0,1"]
PerceivedJustice [pos="2,2"]
TrustinSupervisor [pos="2,0"]
Omitted  [pos="1,1"]
OrgCitizenshipBehavior [pos="3,1"]
#these next 3 lines specify the causal structure, which-causes-which
Monitoring   -> TrustinSupervisor -> OrgCitizenshipBehavior  <- Omitted
TrustinSupervisor <- Omitted
Monitoring  -> PerceivedJustice<- Omitted
}')

# now you can plot the DAG you just created above, see below figure
plot(SpeciousF )




# one can inspect implications of the DAG below
> impliedConditionalIndependencies( SpeciousF )

#there are a few independencies implied by the DAG below:

Monitoring _||_ Omitted
Monitoring _||_ OrgCitizenshipBehavior | Omitted, TrustinSupervisor
OrgCitizenshipBehavior _||_ PerceivedJustice | Monitoring, Omitted
OrgCitizenshipBehavior _||_ PerceivedJustice | Omitted, TrustinSupervisor
PerceivedJustice _||_ TrustinSupervisor | Monitoring, Omitted

#this shows what you HAVE to adjust to estimate the causal effect of Monitoring on OrgCitizenshipBehavior, with {} meaning 'nothing"

adjustmentSets( SpeciousF, "Monitoring", "OrgCitizenshipBehavior ", type="all" )
> adjustmentSets( SpeciousF, "Monitoring", "OrgCitizenshipBehavior", type="all" )
 {}
 { Omitted }
 { Omitted, PerceivedJustice }


Fischer, T., Dietz, J., & Antonakis, J. , 2017, Leadership Process Models. Journal of Management, 0(0), 0149206316682830. http://dx.doi.org/10.1177/0149206316682830