The qgraph package for network visualizations of psychometric data - - PowerPoint PPT Presentation

the qgraph package for network visualizations of
SMART_READER_LITE
LIVE PREVIEW

The qgraph package for network visualizations of psychometric data - - PowerPoint PPT Presentation

The qgraph package for network visualizations of psychometric data in R All codes in these slides were run using R version 2.12.1 (2010-12-16) and qgraph version 0.4.8 and were made on Sacha Epskamp, Angelique O. J. Cramer, Lourens J. Waldorp,


slide-1
SLIDE 1

The qgraph package for network visualizations of psychometric data in R

Sacha Epskamp, Angelique O. J. Cramer, Lourens J. Waldorp, Verena D. Schmittmann and Denny Borsboom

University of Amsterdam Department of Psychological Methods

Psychoco 2011 All codes in these slides were run using R version 2.12.1 (2010-12-16) and qgraph version 0.4.8 and were made on Windows 7 x64 x86-64 build 7600.

qgraph

◮ A R package (CRAN link) ◮ Can be used to plot various types of graphs ◮ Different from other R packages (e.g. igraph Csardi &

Nepusz, 2006) in:

◮ Focus on weighted graphs ◮ Intended for visualization of data as graphs ◮ Optimized for vector-type image files (e.g. PDF, SVG)

◮ Aims in qgraph

◮ Simple input ◮ Summarize a large amount of statistics without needing data

reduction methods.

◮ Visualize relations between variables

◮ Main idea: Show variables as nodes, relationships as edges

Graphs

◮ A graph is a network that consists of n nodes (or vertices)

that are connected with m edges.

◮ Each edge has a weight indicating the strength of that

connection

◮ An edge can be directed (have an arrow) or undirected

slide-2
SLIDE 2

Unweighted graph

1 2 3 4 5 6 7 8 9 10

Weighted graph

1 2 3 4 5 6 7 8 9 10

Weighted graph

1 2 3 4 5 6 7 8 9 10

Directed graph

1 2 3 4 5 6 7 8 9 10

slide-3
SLIDE 3

The qgraph() function

◮ The main function in qgraph is qgraph()

◮ Most other functions are either wrapping functions using

qgraph() or functions used in qgraph()

◮ The qgraph() function requires only one argument (adj) ◮ A lot of other arguments can be specified, but these are all

  • ptional

Usage:

qgraph( adj, ... )

The adjacency matrix

◮ The adj argument is the input. This can be an adjacency

matrix

◮ An adjacency matrix is a square n by n matrix in which each

element indicates the relationship between two variables

◮ Any relationship can be used as long as:

◮ A 0 indicates no relationship ◮ Absolute negative values are similar in strength to positive

values

◮ Examples:

◮ A 1 indicating a connection (unweighted graphs) ◮ Correlations ◮ Regression parameters ◮ Factor loadings

◮ Adjacency matrices occur naturally in statistics!

[,1] [,2] [,3] [1,] 1 1 [2,] 1 [3,]

1 2 3

Weighted graphs

Y = ηΛT + Θ > set.seed(2) > eta <- matrix(rnorm(200 * 5), ncol = 5) > lam <- matrix(rnorm(50 * 5, 0, 0.15), 50, + 5) > lam[apply(diag(5) == 1, 1, rep, each = 10)] <- rnorm(50, + 0.7, 0.3) > th <- matrix(rnorm(200 * 50), ncol = 50) > Y <- eta %*% t(lam) + th

slide-4
SLIDE 4

Weighted graphs

> cor(Y)[1:15, 1:3] [,1] [,2] [,3] [1,] 1.000000000 0.218987651 0.197325805 [2,] 0.218987651 1.000000000 0.231696634 [3,] 0.197325805 0.231696634 1.000000000 [4,] 0.464897112 0.346780772 0.279845144 [5,] 0.295912130 0.275030523 0.209220603 [6,] 0.235201044 0.272947122 0.197676521 [7,] 0.157314986 -0.001815960 -0.027551034 [8,] 0.234392422 0.212721700 0.192401237 [9,] 0.321680277 0.350685995 0.210808452 [10,] 0.204097076 0.277127339 0.148343574 [11,] -0.072734280 -0.000913891 -0.085440215 [12,] 0.052842181 0.105870583 -0.056247479 [13,] 0.001850306 0.025604291 0.081077133 [14,] -0.083391834 -0.088641129 -0.215127641 [15,] -0.055847218 0.007651554 0.004209916

Weighted graphs

> qgraph(cor(Y))

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Weighted graphs

> gr <- list(1:10, 11:20, 21:30, 31:40, 41:50) > qgraph(cor(Y), groups = gr)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Fruchterman-Reingold layout (20 iterations)

slide-5
SLIDE 5

Fruchterman-Reingold layout (500 iterations)

> qgraph(cor(Y), groups = gr, layout = "spring")

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Saving arguments

> Q <- qgraph(cor(Y), groups = gr, layout = "spring", + minimum = 0.2)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Saving arguments

> Q <- qgraph(Q)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Graphical arguments

> Q <- qgraph(Q, esize = 10)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

slide-6
SLIDE 6

Graphical arguments

> Q <- qgraph(Q, vsize = 4)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Graphical arguments

> Q <- qgraph(Q, borders = FALSE)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Graphical arguments

> Q <- qgraph(Q, shape = "square")

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Graphical arguments

> Q <- qgraph(Q, shape = "circle")

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

slide-7
SLIDE 7

Graphical arguments

> Q <- qgraph(Q, vTrans = 150)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Graphical arguments

> qgraph(Q, transparency = T, bg = T, bgcontrol = 5, + filetype = "png", filename = "bg", res = 144, + width = 7, height = 7) [1] "Output stored in C:/Users/Sacha/Documents/Work/qgraph/Psych

Graphical arguments Correlations

> qgraph(cor(Y), layout = "spring", groups = gr, + cut = 0.3, minimum = 0.1, maximum = 1, + graph = "association")

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

slide-8
SLIDE 8

Partial correlations

> qgraph(cor(Y), layout = "spring", groups = gr, + cut = 0.3, minimum = 0.1, maximum = 1, + graph = "concentration")

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Factorial graph

> qgraph(cor(Y), layout = "spring", groups = gr, + cut = 0.2, vsize = 2, esize = 1, borders = F, + graph = "factorial")

  • 1

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Factor loadings

◮ A factor loadings matrix can be visualized using

qgraph.loadings()

◮ There are two wrapper functions that perform an analysis and

send the results to qgraph.loadings():

◮ qgraph.efa() performs an exploratory factor analysis (EFA)

using stats:::factanal

◮ qgraph.pca() performs a principal component analysis (PCA)

using psych:::principal (Revelle, 2010)

◮ These functions use a correlation or covariance matrix as input

Factor loadings: EFA

> qgraph.efa(cor(Y), 5, rotation = "promax", + layout = "tree", vsize = c(3, 10), groups = gr)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

1 2 3 4 5

slide-9
SLIDE 9

Factor loadings: EFA crossloadings

> qgraph.efa(cor(Y), 5, rotation = "promax", + layout = "tree", crossloadings = TRUE, + vsize = c(3, 10), groups = gr, cut = 0.2)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

1 2 3 4 5

Factor loadings: PCA

> qgraph.pca(cor(Y), 5, rotation = "promax", + vsize = c(4, 10), groups = gr, vTrans = 200)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

1 2 3 4 5

Confirmatory Factor Analysis

◮ qgraph.cfa() can be used to fit a simple confirmatory factor

model

◮ Each variable loads on only one factor ◮ Factors are correlated ◮ Scaling by fixing first loading of each factor to 1

◮ This is done with the sem (Fox, 2010) package ◮ Returns a "sem" object ◮ Results can be send to qgraph.sem() for a full report

Confirmatory Factor Analysis

> res <- qgraph.cfa(cov(Y), N = 200, groups = gr, + vsize = c(2, 10))

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

1 2 3 4 5

slide-10
SLIDE 10

Confirmatory Factor Analysis

> qgraph.semModel(res, edge.label.cex = 0.6)

λ2 λ3 λ4 λ5 λ6 λ7 λ8 λ9 λ10 λ12 λ13 λ14 λ15 λ16 λ17 λ18 λ19 λ20 λ22 λ23 λ24 λ25 λ26 λ27 λ28 λ29 λ30 λ32 λ33 λ34 λ35 λ36 λ37 λ38 λ39 λ40 λ42 λ43 λ44 λ45 λ46 λ47λ48λ49λ50 θ1 θ2 θ3 θ4 θ5 θ6 θ7 θ8 θ9 θ10 θ11 θ12 θ13 θ14 θ15 θ16 θ17 θ18 θ19 θ20 θ21 θ22 θ23 θ24 θ25 θ26 θ27 θ28 θ29 θ30 θ31 θ32 θ33 θ34 θ35 θ36 θ37 θ38 θ39 θ40 θ41 θ42 θ43 θ44 θ45 θ46 θ47 θ48 θ49 θ50 ψ5152 ψ5153 ψ5154 ψ5155 ψ5253 ψ5254 ψ5255 ψ5354 ψ5355 ψ5455 ψ11 ψ22 ψ33 ψ44 ψ55

  • 51

1 2 3 4 5 6 7 8 9 10

52

11 12 13 14 15 16 17 18 19 20

53

21 22 23 24 25 26 27 28 29 30

54

31 32 33 34 35 36 37 38 39 40

55

41 42 43 44 45 46 47 48 49 50

Specified model

Confirmatory Factor Analysis

> qgraph(res, edge.label.cex = 0.6)

0.52 0.46 0.36 0.84 0.65 0.47 0.53 0.58 0.37 0.57 0.66 0.47 0.77 0.69 0.24 0.71 0.57 0.6 0.67 0.38 0.57 0.55 0.5 0.72 0.66 0.48 0.61 0.69 0.54 0.6 0.57 0.84 0.41 0.71 0.64 0.19 0.46 0.5 0.67 0.66 0.84 0.79 0.57 0.27 0.31 0.81 0.29 0.45 0.54 0.73 0.79 0.87 0.29 0.58 0.78 0.99 0.72 0.67 0.86 0.68 0.56 0.78 0.41 0.52 0.94 0.5 0.67 0.64 0.55 0.85 0.68 0.69 0.75 0.48 0.57 0.77 0.63 0.53 0.7 0.64 0.68 0.3 0.83 0.5 0.59 0.96 0.79 0.75 0.55 0.56 0.29 0.38 0.67 0.93 0.91 0.34 0.91 0.79 0.71 0.12 0.21 −0.12 1 1 1 1 1

  • 51

1 2 3 4 5 6 7 8 9 10

52

11 12 13 14 15 16 17 18 19 20

53

21 22 23 24 25 26 27 28 29 30

54

31 32 33 34 35 36 37 38 39 40

55

41 42 43 44 45 46 47 48 49 50

Standardized model

Confirmatory Factor Analysis

> qgraph.sem(res, filename = "sem%03d", onefile = F, + panels = 2, legend = FALSE, groups = gr, + edge.label.cex = 0.6)

Confirmatory Factor Analysis

Model statistics Model: Observed variables: 50 / 55 Number of free parameters: 110 Number of observations: 200 Number of fixed exogenous variables: 0 Iterations: 49 Goodness of Fit: Chisq: 1769.10048 , df: 1165 , p= 0 RMSEA: 0.05105 ( 90 % CI: NA − NA ) Goodness−of−fit index: 0.74863 Adjusted goodness−of−fit index: 0.7249 Bentler−Bonnett NFI: 0.58411 Tucker−Lewis NNFI: 0.79028 Bentler CFI: 0.80055 SRMR: 0.09508 BIC: −4403.43926

λ2 λ3 λ4 λ5 λ6 λ7 λ8 λ9 λ10 λ12 λ13 λ14 λ15 λ16 λ17 λ18 λ19 λ20 λ22 λ23 λ24 λ25 λ26 λ27 λ28 λ29 λ30 λ32 λ33 λ34 λ35 λ36 λ37 λ38 λ39 λ40 λ42 λ43 λ44 λ45 λ46 λ47 λ48 λ49 λ50 θ1 θ2 θ3 θ4 θ5 θ6 θ7 θ8 θ9 θ10 θ11 θ12 θ13 θ14 θ15 θ16 θ17 θ18 θ19 θ20 θ21 θ22 θ23 θ24 θ25 θ26 θ27 θ28 θ29 θ30 θ31 θ32 θ33 θ34 θ35 θ36 θ37 θ38 θ39 θ40 θ41 θ42 θ43 θ44 θ45 θ46 θ47 θ48 θ49 θ50 ψ5152 ψ5153 ψ5154 ψ5155 ψ5253 ψ5254 ψ5255 ψ5354 ψ5355 ψ5455 ψ11 ψ22 ψ33 ψ44 ψ55

  • 51

1 2 3 4 5 6 7 8 9 10

52

11 12 13 14 15 16 17 18 19 20

53

21 22 23 24 25 26 27 28 29 30

54

31 32 33 34 35 36 37 38 39 40

55

41 42 43 44 45 46 47 48 49 50

Specified model

slide-11
SLIDE 11

Confirmatory Factor Analysis

1 0.87 0.74 2.5 1.52 1 0.15 1.04 1.31 0.68 1 1.19 0.69 1.64 1.26 0.31 1.28 0.92 0.91 1.14 1 1.64 1.54 1.4 2.9 2.11 1.46 1.9 2.39 1.55 1 0.95 1.75 0.56 1.35 1.12 0.27 0.7 0.7 1.16 1 1.89 1.43 0.76 0.33 0.44 1.59 0.38 0.57 0.74 0.88 0.92 1.2 0.85 1.07 1.16 1.15 0.94 1.13 0.97 1.22 1.06 0.98 1.11 1.04 0.92 0.96 1.02 0.88 0.93 1.05 1.01 0.97 1.05 1.42 1.06 1.29 1.1 1.15 1.02 1.15 1.23 0.86 1.01 1.18 1.18 1.28 1.21 0.95 1.07 0.97 1.11 0.93 0.88 1.07 1.36 0.99 1.15 0.93 1.01 −0.04 0.03 0.1 −0.06 0.02 −0.03 −0.06 0.03 −0.01 −0.06 0.33 0.59 0.18 0.65 0.75

  • 51

1 2 3 4 5 6 7 8 9 10

52

11 12 13 14 15 16 17 18 19 20

53

21 22 23 24 25 26 27 28 29 30

54

31 32 33 34 35 36 37 38 39 40

55

41 42 43 44 45 46 47 48 49 50

Unstandardized model

0.52 0.46 0.36 0.84 0.65 0.47 0.08 0.53 0.58 0.37 0.57 0.66 0.47 0.77 0.69 0.24 0.71 0.57 0.6 0.67 0.38 0.57 0.55 0.5 0.72 0.66 0.48 0.61 0.69 0.54 0.6 0.57 0.84 0.41 0.71 0.64 0.19 0.46 0.5 0.67 0.66 0.84 0.79 0.57 0.27 0.31 0.81 0.29 0.45 0.54 0.73 0.79 0.87 0.29 0.58 0.78 0.99 0.72 0.67 0.86 0.68 0.56 0.78 0.41 0.52 0.94 0.5 0.67 0.64 0.55 0.85 0.68 0.69 0.75 0.48 0.57 0.77 0.63 0.53 0.7 0.64 0.68 0.3 0.83 0.5 0.59 0.96 0.79 0.75 0.55 0.56 0.29 0.38 0.67 0.93 0.91 0.34 0.91 0.79 0.71 −0.09 0.12 0.21 −0.12 0.07 −0.04 −0.1 0.08 −0.01 −0.08 1 1 1 1 1

  • 51

1 2 3 4 5 6 7 8 9 10

52

11 12 13 14 15 16 17 18 19 20

53

21 22 23 24 25 26 27 28 29 30

54

31 32 33 34 35 36 37 38 39 40

55

41 42 43 44 45 46 47 48 49 50

Standardized model

Confirmatory Factor Analysis

  • 51

1 2 3 4 5 6 7 8 9 10

52

11 12 13 14 15 16 17 18 19 20

53

21 22 23 24 25 26 27 28 29 30

54

31 32 33 34 35 36 37 38 39 40

55

41 42 43 44 45 46 47 48 49 50

Unstandardized model

  • 51

1 2 3 4 5 6 7 8 9 10

52

11 12 13 14 15 16 17 18 19 20

53

21 22 23 24 25 26 27 28 29 30

54

31 32 33 34 35 36 37 38 39 40

55

41 42 43 44 45 46 47 48 49 50

Standardized model

Confirmatory Factor Analysis

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 Observed covariances 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 Implied covariances

Confirmatory Factor Analysis

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 Observed correlations 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 Implied correlations

slide-12
SLIDE 12

Confirmatory Factor Analysis

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 Covariance differences 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 Correlation differences

Structural Equation Modelling

◮ qgraph comes with a function that extends output from sem

(Fox, 2010) with path diagrams and graphs visualizing the parameter estimates

◮ This is done with the qgraph.sem() function ◮ The output of qgraph.sem() is a multi-page pdf file ◮ We can use sem as usual and pass the output to

qgraph.sem() with only two things to note:

◮ It is best to limit variable names in the model to three

characters

◮ qgraph supports Greek letters, by adding an asterisk a label is

printed in the symbol font

Structural Equation Modelling

> library('sem') > R.thur <- read.moments(diag=FALSE, names=c('Sen','Voc', + 'SC','FL','4LW','Suf','LS','Ped','LG')) 1: .828 2: .776 .779 4: .439 .493 .46 7: .432 .464 .425 .674 11: .447 .489 .443 .59 .541 16: .447 .432 .401 .381 .402 .288 22: .541 .537 .534 .35 .367 .32 .555 29: .38 .358 .359 .424 .446 .325 .598 .452 37: Read 36 items

Structural Equation Modelling

> model.thur <- specify.model() 1: F1 -> Sen, *l11, NA 2: F1 -> Voc, *l21, NA 3: F1 -> SC, *l31, NA 4: F2 -> FL, *l41, NA 5: F2 -> 4LW, *l52, NA 6: F2 -> Suf, *l62, NA 7: F3 -> LS, *l73, NA 8: F3 -> Ped, *l83, NA 9: F3 -> LG, *l93, NA 10: F4 -> F1, *g1, NA 11: F4 -> F2, *g2, NA 12: F4 -> F3, *g3, NA 13: Sen <-> Sen, q*1, NA 14: Voc<-> Voc, q*2, NA 15: SC <-> SC, q*3, NA

slide-13
SLIDE 13

Structural Equation Modelling

16: FL <-> FL, q*4, NA 17: 4LW <-> 4LW, q*5, NA 18: Suf<-> Suf, q*6, NA 19: LS <-> LS, q*7, NA 20: Ped<-> Ped, q*8, NA 21: LG <-> LG, q*9, NA 22: F1 <-> F1, NA, 1 23: F2 <-> F2, NA, 1 24: F3 <-> F3, NA, 1 25: F4 <-> F4, NA, 1 26: Read 25 records > sem.thur <- sem(model.thur, R.thur, 213)

Structural Equation Modelling

> qgraph(model.thur)

λ11 λ21 λ31 λ41 λ52 λ62 λ73 λ83 λ93 γ1 γ2 γ3 θ1 θ2 θ3 θ4 θ5 θ6 θ7 θ8 θ9

  • F1

Sen Voc

SC F2 FL

4LW Suf

F3 LS

Ped

LG F4

Specified model

Structural Equation Modelling

> qgraph(model.thur, manifest = rownames(R.thur), + layout = "tree")

λ11 λ21 λ31 λ41 λ52 λ62 λ73 λ83 λ93 γ1 γ2 γ3 θ1 θ2 θ3 θ4 θ5 θ6 θ7 θ8 θ9

  • F1

Sen Voc

SC

F2

FL

4LW Suf

F3

LS

Ped

LG

F4

Specified model

Structural Equation Modelling

> qgraph(sem.thur, layout = "tree", curve = 0.4)

0.9 0.91 0.86 0.84 0.8 0.7 0.78 0.72 0.7 0.82 0.78 0.82 0.18 0.16 0.27 0.3 0.36 0.51 0.39 0.48 0.51 0.32 0.39 0.34 1

  • F1

Sen Voc

SC

F2

FL

4LW Suf

F3

LS

Ped

LG

F4

Standardized model

slide-14
SLIDE 14

Structural Equation Modelling

> qgraph(sem.thur, layout = "spring", residuals = FALSE)

0.9 0.91 0.86 0.84 0.8 0.7 0.78 0.72 0.7 0.82 0.78 0.82

F1

Sen Voc

SC

F2

FL

4LW Suf

F3

LS

Ped

LG

F4

Standardized model

The big 5

> library(qgraph) > data(big5) > str(big5) num [1:500, 1:240] 2 3 4 4 5 2 2 1 4 2 ...

  • attr(*, "dimnames")=List of 2

..$ : NULL ..$ : chr [1:240] "N1" "E2" "O3" "A4" ... > data(big5groups) > str(big5groups) List of 5 $ Neuroticism : num [1:48] 1 6 11 16 21 26 31 36 41 46 ... $ Extraversion : num [1:48] 2 7 12 17 22 27 32 37 42 47 ... $ Openness : num [1:48] 3 8 13 18 23 28 33 38 43 48 ... $ Agreeableness : num [1:48] 4 9 14 19 24 29 34 39 44 49 ... $ Conscientiousness: num [1:48] 5 10 15 20 25 30 35 40 45 50 ..

The big 5

> Q <- qgraph(cor(big5), minimum = 0.25, cut = 0.4, + vsize = 2, groups = big5groups, legend = T, + borders = F, vTrans = 200)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240

  • Neuroticism

Extraversion Openness Agreeableness Conscientiousness

  • Neuroticism

Extraversion Openness Agreeableness Conscientiousness

The big 5

> qgraph(cor(big5), Q, layout = "spring")

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240

  • Neuroticism

Extraversion Openness Agreeableness Conscientiousness

  • Neuroticism

Extraversion Openness Agreeableness Conscientiousness

slide-15
SLIDE 15

EFA

> qgraph.efa(cor(big5), factors = 5, Q, layout = "circle", + vsize = c(1, 15), borders = F, asize = 0.07, + esize = 4, rotation = "promax", residSize = 0.1)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240

Neuroticism Extraversion

Conscientiousness

Agreeableness

Openness

Concluding comments

◮ qgraph is still work in progress ◮ Plans for the future:

◮ More wrapper functions for different statistics (e.g. IRT) ◮ More layout modes ◮ Estimating and fitting causal models

◮ Some things I couldn’t describe...

Layout constraints Grayscale colors

> Q <- qgraph(cor(big5), minimum = 0.25, cut = 0.4, + vsize = 2, groups = big5groups, legend = T, + borders = F, vTrans = 200, gray = TRUE)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240

  • Neuroticism

Extraversion Openness Agreeableness Conscientiousness

  • Neuroticism

Extraversion Openness Agreeableness Conscientiousness

  • 1

2 3

slide-16
SLIDE 16

Tooltips

Link

Modelling ξ η1 η2 η3

y1 y2 y3 y4 y5 y6 y7 x1 x2 x3

  • americas
enduring strength httpfbmesashrd httpfbmepfjwduip tragedy arizona httpfbmefcgtvdg price gold
  • unce
hour finale sarah palins alaska youll httpfbmeyvidei please remember watch live webcast haiti rev franklin grahams festival hope tomorrow pm httpfbmejgnrl samaritans pursefranklin sunday portauprince @ wsamaritanspurseorghaitilive march
  • bama
raising debt weakens usa signals failed leadership support
  • verspendingnow
raise ceiling congrats spkr boehnerappreciate ur humble words accepting peoples house leadershipnow action
  • utofcontrol
govt dependence foreign
  • il
@amsol mt @saeverley top #obama gas prices httpbitlyfokq #drillnow #energy alaskas energy resources strategic location noted

nd

bday

rt

htpconservativespalincomhapyndbirthdayalaskahtml merry christmas httpfbmenoenbhzt enjoy alaskan rendition hallelujah chorus assembled children kuinerrarmiut elitnaurviat httpfbmeescwcvd follow afognak island httpfbmemzznov greta van susterens record tonight et fox news channel httpfbmealanyfp private voluntary contributions beat bureaucracy times tonite vansusteren effective faithbased aid helping httpfbmekdkslp heres sneak preview special airs thursday dec rd httpfbmedczjtzd tune httpfbmeqslvohgg time tough iran httpfbmecviatcq quads bogs bones httpfbmegipvrjf
  • mnibus
defeat victory reality httpfbmepuuvzfk delink missile defense start httpfbmeqjerdit tax deal estate spending status quo rates bush era codified temporarythus cont uncertainty takes cake @amandacarpenter ap flubs palin hair bristol mom httpbitlyhpwgyc life circumstances reaction sundays ak hospitality episode illustrates bit @wsjopinion ryan roadmap settle biggovernment httponwsjcomifukmq link wsj
  • ped
rep paul ryans government httpfbmeoxqwbgnu nope silly uninformed folks nec narnia cs lewis fellow@
  • xford
chair@ cambridge read uninspired screwtape lettersmere christianityeven yorker agrees witwisdom stylescholarship requisitescslewis angels leatherbound edition america heart book signing date httpfbmemcgfbge solvency sowell htpwashingtonexaminercomopinioncolumniststhomasoweltaxcutrhetoricdoesntcutit
  • bviously
wrong economy spins gop cut goalsso fiscal conservatives expect fight sue secretary @spalaska aikens life@ kavik river Cutoff: 0.3 Minimum: 0.1 Maximum: 1

Concluding comments

Thank you for your attention!

slide-17
SLIDE 17

References

Butts, C. T. (2010). sna: Tools for social network analysis [Computer software manual]. Available from http://CRAN.R-project.org/package=sna (R package version 2.2-0) Csardi, G., & Nepusz, T. (2006). The igraph software package for complex network research. InterJournal, Complex Systems,

  • 1695. Available from http://igraph.sf.net

Fox, J. (2010). sem: Structural equation models [Computer software manual]. Available from http://CRAN.R-project.org/package=sem (R package version 0.9-21) Fruchterman, T., & Reingold, E. (1991). Graph drawing by force-directed placement. Software: Practice and Experience, 21(11), 1129–1164. Revelle, W. (2010). psych: Procedures for psychological, psychometric, and personality research [Computer software manual]. Evanston, Illinois. Available from http:// personality-project.org/r/psych.manual.pdf (R package version 1.0-93)

Layout modes

◮ The placement of the nodes is specified with the layout

argument in qgraph()

◮ This can be a n by 2 matrix indicating the x and y position of

each node

◮ layout can also be given a character indicating one of the

two default layouts

◮ If layout="circular" the nodes are placed in circles per

group (if the groups list is specified)

◮ If layout="spring" a force-embedded algorithm

(Fruchterman & Reingold, 1991) is used for the placement

◮ This is an iterative algorithm that clusters the nodes so that

the length of the edges correspond to the absolute strength of the edges

Fruchterman-Reingold layout (20 iterations) Fruchterman-Reingold layout (500 iterations)

> qgraph(cor(Y), groups = gr, layout = "spring")

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

slide-18
SLIDE 18

Grid layout

◮ A final option is to specify a grid as layout ◮ This can be done by specifying a matrix to layout with more

than two columns

◮ This matrix contains zeros and a number for each node

> dat.3 <- matrix(c(1:15 * 2 - 1, 1:15 * 2), + , 2) > dat.3 <- cbind(dat.3, round(seq(-0.7, 0.7, + length = 15), 1)) > L.3 <- matrix(1:30, nrow = 2) > L.3 [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [1,] 1 3 5 7 9 11 13 15 17 [2,] 2 4 6 8 10 12 14 16 18 [,10] [,11] [,12] [,13] [,14] [,15] [1,] 19 21 23 25 27 29 [2,] 20 22 24 26 28 30

Grid layout

> qgraph(dat.3, layout = L.3, directed = FALSE)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Fruchterman-Reingold layout

◮ layout="spring" uses a force-embedded algorithm that was

proposed by Fruchterman and Reingold (1991)

◮ This layout was ported from the sna package (Butts, 2010) ◮ A solution for weighted graphs was taken from igraph (Csardi

& Nepusz, 2006)

◮ This is an iterative algorithm. ◮ The initial layout is a circle ◮ Then in each iteration:

◮ Each node is repulsed by all other nodes ◮ Connected nodes are also attracted to each other ◮ The maximum displacement weakens each iteration

◮ After this process the layout is rescaled to fit the −1 to 1

xy-plane

◮ The unscaled layout is returned as layout.orig

Fruchterman-Reingold layout

◮ The Fruchterman-Reingold algorithm can be controlled with

the layout.par argument

◮ This must be a list containing other arguments:

niter Number of iterations, default is 500 max.delta Maximum displacement, default is n area The area of the plot, default is n2 cool.exp Cooling exponent, default is 1.5 repulse.rad Repulse radius, default is n · area init Matrix indicating initial layout

slide-19
SLIDE 19

Constraints in the Fruchterman-Reingold layout

◮ The Fruchterman-Reingold algorithm behaves like a chaotic

system

◮ A small difference in initial setup can result in a completely

different layout

◮ In qgraph the layout can be constrained to compensate this ◮ Hard constraints

◮ Hard constraints can be used to fix the x and y position of

certain nodes

◮ This can be done with the constraints argument in

layout.par

◮ Soft constraints

◮ Soft constraints can be used to limit the displacement of

certain nodes

◮ This can be done with the max.delta and init arguments in

layout.par

No constraints

> dat.3 <- matrix(c(1, 2, 1, 3, 2, 3), 3, 2, + byrow = T) > L <- matrix(c(1:3, 1, 3, 1), 3, 2) > Q <- qgraph(dat.3, layout = L, vsize = 3, + esize = 1) > par <- list(init = L) > set.seed(1) > for (i in 3:20) { + dat.3 <- rbind(dat.3, c(sample(c(i, sample(1:i, + 1)), 1), i + 1)) + L <- rbind(L, 0) + par$init <- L + L <- qgraph(dat.3, Q, layout.par = par, + layout = "spring")$layout.orig + }

No constraints Hard constraints

> dat.3 <- matrix(c(1, 2, 1, 3, 2, 3), 3, 2, + byrow = T) > L <- matrix(c(1:3, 1, 3, 1), 3, 2) > par <- list(max.delta = 10, area = 10^2, + repulse.rad = 10^3) > Q <- qgraph(dat.3, layout = L, vsize = 3, + esize = 1, layout.par = par) > set.seed(1) > for (i in 3:20) { + dat.3 <- rbind(dat.3, c(sample(c(i, sample(1:i, + 1)), 1), i + 1)) + par$init <- rbind(L, 0) + L <- rbind(L, NA) + par$constraints <- L + L <- qgraph(dat.3, Q, layout.par = par, + layout = "spring")$layout.orig + }

  • 1

2 3

slide-20
SLIDE 20

Hard constraints Soft constraints

> dat.3 <- matrix(c(1, 2, 1, 3, 2, 3), 3, 2, + byrow = T) > L <- matrix(c(1:3, 1, 3, 1), 3, 2) > par <- list(max.delta = 10, area = 10^2, + repulse.rad = 10^3) > Q <- qgraph(dat.3, layout = L, vsize = 3, + esize = 1, layout.par = par) > set.seed(1) > for (i in 3:20) { + dat.3 <- rbind(dat.3, c(sample(c(i, sample(1:i, + 1)), 1), i + 1)) + par$init <- rbind(L, 0) + L <- rbind(L, NA) + par$max.delta <- 10/(i + 1):1 + L <- qgraph(dat.3, Q, layout.par = par, + layout = "spring")$layout.orig + }

Soft constraints Interpreting weighted graphs

> qgraph(dat.3, layout = L.3, directed = FALSE, + edge.labels = T)

−0.7 −0.6 −0.5 −0.4 −0.3 −0.2 −0.1 0.1 0.2 0.3 0.4 0.5 0.6 0.7

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

  • 1

2 3

  • 1

2 3

slide-21
SLIDE 21

Interpreting weighted graphs

> qgraph(dat.3, layout = L.3, directed = FALSE, + edge.labels = T, esize = 14)

−0.7 −0.6 −0.5 −0.4 −0.3 −0.2 −0.1 0.1 0.2 0.3 0.4 0.5 0.6 0.7

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Interpreting weighted graphs

> qgraph(dat.3[-c(1:3, 13:15), ], layout = L.3, + nNodes = 30, directed = FALSE, edge.labels = T, + esize = 14)

−0.4 −0.3 −0.2 −0.1 0.1 0.2 0.3 0.4

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Interpreting weighted graphs

> qgraph(dat.3, layout = L.3, directed = FALSE, + edge.labels = T, esize = 14, maximum = 1)

−0.7 −0.6 −0.5 −0.4 −0.3 −0.2 −0.1 0.1 0.2 0.3 0.4 0.5 0.6 0.7

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Interpreting weighted graphs

> qgraph(dat.3[-c(1:3, 13:15), ], layout = L.3, + nNodes = 30, directed = FALSE, edge.labels = T, + esize = 14, maximum = 1)

−0.4 −0.3 −0.2 −0.1 0.1 0.2 0.3 0.4

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

slide-22
SLIDE 22

Interpreting weighted graphs

maximum must be set to be able to compare multiple graphs!

Interpreting weighted graphs

> qgraph(dat.3, layout = L.3, directed = FALSE, + edge.labels = T, esize = 14, minimum = 0.1)

−0.7 −0.6 −0.5 −0.4 −0.3 −0.2 0.2 0.3 0.4 0.5 0.6 0.7

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Interpreting weighted graphs

> qgraph(dat.3, layout = L.3, directed = FALSE, + edge.labels = T, esize = 14, cut = 0.4)

−0.7 −0.6 −0.5 −0.4 −0.3 −0.2 −0.1 0.1 0.2 0.3 0.4 0.5 0.6 0.7

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Interpreting weighted graphs

> qgraph(dat.3, layout = L.3, directed = FALSE, + edge.labels = T, esize = 14, minimum = 0.1, + maximum = 1, cut = 0.4, details = TRUE)

−0.7 −0.6 −0.5 −0.4 −0.3 −0.2 0.2 0.3 0.4 0.5 0.6 0.7

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Cutoff: 0.4 Minimum: 0.1 Maximum: 1

slide-23
SLIDE 23

Interpreting weighted graphs

Graphs can not be interpreted without knowing minimum, cut and maximum!