Upload
others
View
6
Download
0
Embed Size (px)
Citation preview
The qgraph package for network visualizations ofpsychometric data in R
Sacha Epskamp, Angelique O. J. Cramer, Lourens J. Waldorp,Verena D. Schmittmann and Denny Borsboom
University of AmsterdamDepartment 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 onWindows 7 x64 x86-64 build 7600.
qgraph
I A R package (CRAN link)
I Can be used to plot various types of graphsI Different from other R packages (e.g. igraph Csardi &
Nepusz, 2006) in:I Focus on weighted graphsI Intended for visualization of data as graphsI Optimized for vector-type image files (e.g. PDF, SVG)
I Aims in qgraphI Simple inputI Summarize a large amount of statistics without needing data
reduction methods.I Visualize relations between variables
I Main idea: Show variables as nodes, relationships as edges
Graphs
I A graph is a network that consists of n nodes (or vertices)that are connected with m edges.
I Each edge has a weight indicating the strength of thatconnection
I An edge can be directed (have an arrow) or undirected
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
The qgraph() function
I The main function in qgraph is qgraph()I Most other functions are either wrapping functions using
qgraph() or functions used in qgraph()
I The qgraph() function requires only one argument (adj)
I A lot of other arguments can be specified, but these are alloptional
Usage:
qgraph( adj, ... )
The adjacency matrix
I The adj argument is the input. This can be an adjacencymatrix
I An adjacency matrix is a square n by n matrix in which eachelement indicates the relationship between two variables
I Any relationship can be used as long as:I A 0 indicates no relationshipI Absolute negative values are similar in strength to positive
values
I Examples:I A 1 indicating a connection (unweighted graphs)I CorrelationsI Regression parametersI Factor loadings
I Adjacency matrices occur naturally in statistics!
[,1] [,2] [,3]
[1,] 0 1 1
[2,] 0 0 1
[3,] 0 0 0
1
23
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
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 34
56
78
9
10
11
12
13
14
15
16
17
18
1920
2122
232425262728
2930
3132
33
34
35
36
37
38
39
40
41
42
43
4445
4647
4849 50
Weighted graphs
> gr <- list(1:10, 11:20, 21:30, 31:40, 41:50)
> qgraph(cor(Y), groups = gr)
12
3
4
56
7
8
9
10
1112
13
14
1516
17
18
19
20
2122
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
40
4142
43
44
4546
47
48
49
50
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
4748
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
4748
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
4748
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
4748
49
50
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
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/Psychoco2011/bg.png"
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
4748
49
50
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
78
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2627
2829
3031
3233
34
35
36
37
38
39
40
4142
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")
●●
●
●
●●
●
●
● ●
●
●
●
●
●
●
●●
●●
●●
●
●
●●
●●
●●
●
●
●●
●
● ●
●
●
●
●
●
●
●
●
●
●
●
●●
12
3
4
56
7
8
9 10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2526
2728
2930
31
32
33
34
35
36 37
38
39
40
41
42
43
44
45
46
47
48
4950
Factor loadings
I A factor loadings matrix can be visualized usingqgraph.loadings()
I There are two wrapper functions that perform an analysis andsend the results to qgraph.loadings():
I qgraph.efa() performs an exploratory factor analysis (EFA)using stats:::factanal
I qgraph.pca() performs a principal component analysis (PCA)using psych:::principal (Revelle, 2010)
I 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 1011 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 4041 42 43 44 45 46 47 48 49 50
1 2 3 4 5
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 1011 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 4041 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
45
67
89 10 11 12 13
1415
1617
18
19
20
2122
232425262728
2930
3132
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
4950
1
2
3
4
5
Confirmatory Factor Analysis
I qgraph.cfa() can be used to fit a simple confirmatory factormodel
I Each variable loads on only one factorI Factors are correlatedI Scaling by fixing first loading of each factor to 1
I This is done with the sem (Fox, 2010) package
I Returns a "sem" object
I 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 23
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2324
25262728
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
4849
50
1
2
3
4
5
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 34
56
7
8
9
10
52
11
12
13
14
15
16
17
18
19
20
53
2122
232425262728
2930
54
31
32
33
34
35
36
37
38
39
40
5541
42
43
44
45
4647
4849 50
Specified model
Confirmatory Factor Analysis
> qgraph(res, edge.label.cex = 0.6)
0.520.460.360.840.65
0.47
0.530.58
0.37
0.57
0.66
0.47
0.77
0.69
0.24
0.710.57
0.60.67
0.380.57
0.550.50.720.660.480.610.690.54
0.60.57
0.840.41
0.71
0.64
0.19
0.46
0.5
0.67
0.66
0.840.79
0.570.27
0.310.81
0.290.450.54
0.73 0.790.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.690.75
0.480.570.770.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.910.79
0.71
0.12
0.21
−0.12
1
1
1
1
1
● ●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●●●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●
●
51
1 2 34
56
7
8
9
10
52
11
12
13
14
15
16
17
18
19
20
53
2122
232425262728
2930
54
31
32
33
34
35
36
37
38
39
40
5541
42
43
44
45
4647
4849 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 23
4
5
6
7
8
9
10
52
11
12
13
14
15
16
17
18
19
20
53
21
22
2324
25262728
29
30
54
31
32
33
34
35
36
37
38
39
40
5541
42
43
44
45
46
47
4849
50
Specified model
Confirmatory Factor Analysis
1 0.87 0.742.5
1.521
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
11.64
1.541.42.92.111.461.9
2.391.55
10.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.330.44
1.590.38
0.57 0.74
0.88 0.921.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.051.421.061.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.931.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 23
4
5
6
7
8
9
10
52
11
12
13
14
15
16
17
18
19
20
53
21
22
2324
25262728
29
30
54
31
32
33
34
35
36
37
38
39
40
5541
42
43
44
45
46
47
4849
50
Unstandardized model
0.52 0.46 0.360.84
0.650.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.380.57
0.550.50.720.660.480.61
0.690.54
0.60.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.270.31
0.810.29
0.45 0.54
0.73 0.790.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.750.480.570.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.790.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 23
4
5
6
7
8
9
10
52
11
12
13
14
15
16
17
18
19
20
53
21
22
2324
25262728
29
30
54
31
32
33
34
35
36
37
38
39
40
5541
42
43
44
45
46
47
4849
50
Standardized model
Confirmatory Factor Analysis
● ●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●
51
1 23
4
5
6
7
8
9
10
52
11
12
13
14
15
16
17
18
19
20
53
21
22
2324
25262728
29
30
54
31
32
33
34
35
36
37
38
39
40
5541
42
43
44
45
46
47
4849
50
Unstandardized model
● ●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●
51
1 23
4
5
6
7
8
9
10
52
11
12
13
14
15
16
17
18
19
20
53
21
22
2324
25262728
29
30
54
31
32
33
34
35
36
37
38
39
40
5541
42
43
44
45
46
47
4849
50
Standardized model
Confirmatory Factor Analysis
12
3
4
56
7
8
9
10
1112
13
14
1516
17
18
19
20
2122
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
40
4142
43
44
4546
47
48
49
50
Observed covariances
12
3
4
56
7
8
9
10
1112
13
14
1516
17
18
19
20
2122
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
40
4142
43
44
4546
47
48
49
50
Implied covariances
Confirmatory Factor Analysis
12
3
4
56
7
8
9
10
1112
13
14
1516
17
18
19
20
2122
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
40
4142
43
44
4546
47
48
49
50
Observed correlations
12
3
4
56
7
8
9
10
1112
13
14
1516
17
18
19
20
2122
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
40
4142
43
44
4546
47
48
49
50
Implied correlations
Confirmatory Factor Analysis
12
3
4
56
7
8
9
10
1112
13
14
1516
17
18
19
20
2122
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
40
4142
43
44
4546
47
48
49
50
Covariance differences
12
3
4
56
7
8
9
10
1112
13
14
1516
17
18
19
20
2122
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
40
4142
43
44
4546
47
48
49
50
Correlation differences
Structural Equation Modelling
I qgraph comes with a function that extends output from sem(Fox, 2010) with path diagrams and graphs visualizing theparameter estimates
I This is done with the qgraph.sem() function
I The output of qgraph.sem() is a multi-page pdf fileI We can use sem as usual and pass the output to
qgraph.sem() with only two things to note:I It is best to limit variable names in the model to three
charactersI 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
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
LSPed
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
Structural Equation Modelling
> qgraph(sem.thur, layout = "spring", residuals = FALSE)
0.90.91
0.86
0.84
0.8
0.7
0.78
0.72
0.7
0.82
0.78
0.82
F1Sen
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
34
5
6
7
89
10
11
12
1314
15
16
17
1819
20
21
22
2324
25
26
27
2829
30
31
32
3334
35
36
37
3839
40
41
42
4344
45
46
47
4849
50
51
52
5354
55
56
57
5859
60
61
62
6364
65
66
67
6869
70
71
72
7374
75
76
77
7879
80
81
82
8384
85
86
87
8889
90
91
92
9394
95
96
97
9899
100
101
102
103104
105
106
107
108109
110
111
112
113114
115
116
117
118119
120
121
122
123124
125
126
127
128129
130
131
132
133134
135
136
137
138139
140
141
142
143144
145
146
147
148149
150
151
152
153154
155
156
157
158159
160
161
162
163164
165
166
167
168169
170
171
172
173174
175
176
177
178179
180
181
182
183184
185
186
187
188189
190
191
192
193194
195
196
197
198199
200
201
202
203204
205
206
207
208209
210
211
212
213214
215
216
217
218219
220
221
222
223224
225
226
227
228229
230
231
232
233234
235
236
237
238239
240
●
●
●
●
●
NeuroticismExtraversionOpennessAgreeablenessConscientiousness
●
●
●
●
●
NeuroticismExtraversionOpennessAgreeablenessConscientiousness
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
2425
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
6162
63
64
65
66
67
68
69
70
71
72
73
74
75
7677
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
198199
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
●
●
●
●
●
NeuroticismExtraversionOpennessAgreeablenessConscientiousness
●
●
●
●
●
NeuroticismExtraversionOpennessAgreeablenessConscientiousness
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
23
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
I qgraph is still work in progressI Plans for the future:
I More wrapper functions for different statistics (e.g. IRT)I More layout modesI Estimating and fitting causal models
I 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
34
5
6
7
89
10
11
12
1314
15
16
17
1819
20
21
22
2324
25
26
27
2829
30
31
32
3334
35
36
37
3839
40
41
42
4344
45
46
47
4849
50
51
52
5354
55
56
57
5859
60
61
62
6364
65
66
67
6869
70
71
72
7374
75
76
77
7879
80
81
82
8384
85
86
87
8889
90
91
92
9394
95
96
97
9899
100
101
102
103104
105
106
107
108109
110
111
112
113114
115
116
117
118119
120
121
122
123124
125
126
127
128129
130
131
132
133134
135
136
137
138139
140
141
142
143144
145
146
147
148149
150
151
152
153154
155
156
157
158159
160
161
162
163164
165
166
167
168169
170
171
172
173174
175
176
177
178179
180
181
182
183184
185
186
187
188189
190
191
192
193194
195
196
197
198199
200
201
202
203204
205
206
207
208209
210
211
212
213214
215
216
217
218219
220
221
222
223224
225
226
227
228229
230
231
232
233234
235
236
237
238239
240
●
●
●
●
●
NeuroticismExtraversionOpennessAgreeablenessConscientiousness
●
●
●
●
●
NeuroticismExtraversionOpennessAgreeablenessConscientiousness
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
ounce
hour
finale
sarah
palins
alaska
youll
httpfbmeyvidei
please
remember
watch
live
webcast
haiti
rev
franklin
grahams
festival
hopetomorrow
pm
httpfbmejgnrl
samaritans
pursefranklin
sunday
portauprince
@
wwwsamaritanspurseorghaitilive
march
obama
raising
debt
weakens
usa
signals
failed
leadership
support
overspendingnow
raise
ceiling
congrats
spkr
boehnerappreciate
ur
humble
words
accepting
peoples
house
leadershipnow
action
outofcontrol
govt
dependence
foreign
oil
@amsol
mt
@saeverley
top
#obama
gas
prices
httpbitlyfokq
#drillnow
#energy
alaskas
energy
resources
strategic
location
noted
nd
bday
rt
httpconservativespalincomhappyndbirthdayalaskahtml
merry
christmas
httpfbmenoenbhzt
enjoy
alaskan
rendition
hallelujah
chorus
assembled
children
kuinerrarmiut
elitnaurviat
httpfbmeescwcvd
follow
afognak
island
httpfbmemzznov
greta
van
susterens
record
tonight
etfox
news
channel
httpfbmealanyfp
private
voluntary
contributions
beat
bureaucracy
times
tonite
vansusteren
effective
faithbased
aid
helpinghttpfbmekdkslp
heres
sneak
preview
special
airs
thursday
dec
rd
httpfbmedczjtzd
tune
httpfbmeqslvohgg
time
tough
iran
httpfbmecviatcq
quads
bogs
bones
httpfbmegipvrjf
omnibus
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
oped
rep
paul
ryans
government
httpfbmeoxqwbgnu
nope
silly
uninformed
folks
nec
narnia
cs
lewis
fellow@
oxford
chair@
cambridge
read
uninspired
screwtape
lettersmere
christianityeven
yorker
agrees
witwisdom
stylescholarship
requisitescslewis
angels
leatherbound
edition
america
heart
book
signing
date
httpfbmemcgfbge
solvency
sowell
httpwashingtonexaminercomopinioncolumniststhomassowelltaxcutrhetoricdoesntcutit
obviously
wrong
economy
spins
gop
cut
goalsso
fiscal
conservatives
expect
fight
sue
secretary
@spalaska
aikens
life@
kavikriver
Cutoff: 0.3Minimum: 0.1 Maximum: 1
Concluding comments
Thank you for your attention!
ReferencesButts, C. T. (2010). sna: Tools for social network analysis
[Computer software manual]. Available fromhttp://CRAN.R-project.org/package=sna (R packageversion 2.2-0)
Csardi, G., & Nepusz, T. (2006). The igraph software package forcomplex network research. InterJournal, Complex Systems,1695. Available from http://igraph.sf.net
Fox, J. (2010). sem: Structural equation models [Computersoftware manual]. Available fromhttp://CRAN.R-project.org/package=sem (R packageversion 0.9-21)
Fruchterman, T., & Reingold, E. (1991). Graph drawing byforce-directed placement. Software: Practice and Experience,21(11), 1129–1164.
Revelle, W. (2010). psych: Procedures for psychological,psychometric, and personality research [Computer softwaremanual]. Evanston, Illinois. Available from http://
personality-project.org/r/psych.manual.pdf (Rpackage version 1.0-93)
Layout modes
I The placement of the nodes is specified with the layout
argument in qgraph()
I This can be a n by 2 matrix indicating the x and y position ofeach node
I layout can also be given a character indicating one of thetwo default layouts
I If layout="circular" the nodes are placed in circles pergroup (if the groups list is specified)
I If layout="spring" a force-embedded algorithm(Fruchterman & Reingold, 1991) is used for the placement
I This is an iterative algorithm that clusters the nodes so thatthe length of the edges correspond to the absolute strength ofthe 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
4748
49
50
Grid layout
I A final option is to specify a grid as layout
I This can be done by specifying a matrix to layout with morethan two columns
I 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
I layout="spring" uses a force-embedded algorithm that wasproposed by Fruchterman and Reingold (1991)
I This layout was ported from the sna package (Butts, 2010)I A solution for weighted graphs was taken from igraph (Csardi
& Nepusz, 2006)
I This is an iterative algorithm.
I The initial layout is a circleI Then in each iteration:
I Each node is repulsed by all other nodesI Connected nodes are also attracted to each otherI The maximum displacement weakens each iteration
I After this process the layout is rescaled to fit the −1 to 1xy -plane
I The unscaled layout is returned as layout.orig
Fruchterman-Reingold layout
I The Fruchterman-Reingold algorithm can be controlled withthe layout.par argument
I This must be a list containing other arguments:
niter Number of iterations, default is 500max.delta Maximum displacement, default is n
area The area of the plot, default is n2
cool.exp Cooling exponent, default is 1.5repulse.rad Repulse radius, default is n · area
init Matrix indicating initial layout
Constraints in the Fruchterman-Reingold layout
I The Fruchterman-Reingold algorithm behaves like a chaoticsystem
I A small difference in initial setup can result in a completelydifferent layout
I In qgraph the layout can be constrained to compensate this
I Hard constraintsI Hard constraints can be used to fix the x and y position of
certain nodesI This can be done with the constraints argument in
layout.par
I Soft constraintsI Soft constraints can be used to limit the displacement of
certain nodesI 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
+ }
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
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
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
30Cutoff: 0.4Minimum: 0.1 Maximum: 1
Interpreting weighted graphs
Graphs can not be interpreted without knowing minimum, cutand maximum!