statsample-sem 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +0 -0
- data/History.txt +3 -0
- data/Manifest.txt +18 -0
- data/README.txt +56 -0
- data/Rakefile +16 -0
- data/bin/statsample_sem +3 -0
- data/example/normal_vs_saturated.rb +36 -0
- data/lib/statsample/sem.rb +46 -0
- data/lib/statsample/sem/model.rb +244 -0
- data/lib/statsample/sem/openmxengine.rb +144 -0
- data/lib/statsample/sem/semjfoxengine.rb +197 -0
- data/spec/fixtures/demo_open_mx.csv +501 -0
- data/spec/fixtures/demo_open_mx.ds +0 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/statsample_sem_model_spec.rb +158 -0
- data/spec/statsample_sem_openmxengine_spec.rb +142 -0
- data/spec/statsample_sem_semjfoxengine_spec.rb +116 -0
- data/spec/statsample_sem_spec.rb +36 -0
- metadata +171 -0
- metadata.gz.sig +0 -0
Binary file
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
puts "Statsample-SEM specs: Running on Ruby Version: #{RUBY_VERSION}"
|
4
|
+
|
5
|
+
require "rubygems"
|
6
|
+
require 'spec'
|
7
|
+
require 'spec/autorun'
|
8
|
+
require 'statsample'
|
9
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
10
|
+
require 'statsample/sem'
|
@@ -0,0 +1,158 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)+"/.")
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Statsample::SEM::Model do
|
5
|
+
before(:all) do
|
6
|
+
begin
|
7
|
+
@data_path=File.dirname(__FILE__)+"/fixtures/demo_open_mx.ds"
|
8
|
+
@ds=Statsample.load(@data_path)
|
9
|
+
rescue
|
10
|
+
@data_path=File.dirname(__FILE__)+"/fixtures/demo_open_mx.csv"
|
11
|
+
@ds=Statsample::CSV.read(@data_path)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
@model=Statsample::SEM::Model.new
|
17
|
+
end
|
18
|
+
it "method manifests= should set manifests" do
|
19
|
+
@model.manifests=@ds.fields
|
20
|
+
@model.manifests.should==@ds.fields
|
21
|
+
end
|
22
|
+
it "method manifests with argument should set manifests" do
|
23
|
+
@model.manifests @ds.fields
|
24
|
+
@model.manifests.should==@ds.fields
|
25
|
+
end
|
26
|
+
it "method latents= should set latents" do
|
27
|
+
@model.latents=["G"]
|
28
|
+
@model.latents.should==["G"]
|
29
|
+
end
|
30
|
+
it "method latents with argument should set latents" do
|
31
|
+
@model.latents ["G"]
|
32
|
+
@model.latents.should==["G"]
|
33
|
+
end
|
34
|
+
it "should automaticly set manifest and latents with data and path" do
|
35
|
+
@model.data_from_matrix(Statsample::Bivariate.covariance_matrix(@ds), :cases=>@ds.dup_only_valid.cases)
|
36
|
+
@model.path :from=>"G1", :to=>['x1','x2']
|
37
|
+
@model.path :from=>"G2", :to=>['x3','x4']
|
38
|
+
@model.latents.should==['G1','G2']
|
39
|
+
@model.manifests.should==['x1','x2','x3','x4']
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
it "method path with :from should create a variance path" do
|
45
|
+
@model.path :from=>"x1"
|
46
|
+
@model.paths.should=={
|
47
|
+
['x1','x1']=>{:from=>'x1',:to=>'x1',:arrow=>2,:label=>'var x1', :free=>true, :value=>nil}
|
48
|
+
}
|
49
|
+
end
|
50
|
+
it "method path with :from and :two should create a regression path" do
|
51
|
+
@model.path :from=>"G", :to=>'x1'
|
52
|
+
@model.paths.should=={
|
53
|
+
['G','x1']=>{:from=>'G',:to=>'x1',:arrow=>1,:label=>'G to x1', :free=>true, :value=>nil}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
it "method path with :from, :two and arrows should set label automaticly" do
|
57
|
+
@model.path :from=>"G", :to=>'x1', :arrows=>1
|
58
|
+
@model.path :from=>"G", :to=>'x2', :arrows=>2
|
59
|
+
|
60
|
+
@model.paths.should=={
|
61
|
+
['G','x1']=>{:from=>'G',:to=>'x1',:arrow=>1,:label=>'G to x1', :free=>true, :value=>nil},
|
62
|
+
['G','x2']=>{:from=>'G',:to=>'x2',:arrow=>2,:label=>'G cov x2', :free=>true, :value=>nil}
|
63
|
+
}
|
64
|
+
end
|
65
|
+
it "method path should label correctly" do
|
66
|
+
@model.path :from=>"G", :to=>['x1','x2','x3'], :labels=>['to x1','to x2']
|
67
|
+
@model.paths.should=={
|
68
|
+
['G','x1']=>{:from=>'G',:to=>'x1',:arrow=>1,:label=>'to x1', :free=>true, :value=>nil},
|
69
|
+
['G','x2']=>{:from=>'G',:to=>'x2',:arrow=>1,:label=>'to x2', :free=>true, :value=>nil},
|
70
|
+
['G','x3']=>{:from=>'G',:to=>'x3',:arrow=>1,:label=>'G to x3', :free=>true, :value=>nil}
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
it "method path with free array set values in proper order" do
|
77
|
+
@model.path :from=>"G", :to=>['x1','x2','x3'], :free=>[false,true,false], :values=>[1,2,3]
|
78
|
+
@model.paths.should=={
|
79
|
+
['G','x1']=>{:from=>'G',:to=>'x1',:arrow=>1,:label=>'G to x1', :free=>false, :value=>1},
|
80
|
+
['G','x2']=>{:from=>'G',:to=>'x2',:arrow=>1,:label=>'G to x2', :free=>true, :value=>nil},
|
81
|
+
['G','x3']=>{:from=>'G',:to=>'x3',:arrow=>1,:label=>'G to x3', :free=>false, :value=>3}
|
82
|
+
}
|
83
|
+
end
|
84
|
+
it "method path with free array set scalar value in proper order" do
|
85
|
+
@model.path :from=>"G", :to=>['x1','x2','x3'], :free=>[false,true,false], :values=>1.0
|
86
|
+
@model.paths.should=={
|
87
|
+
['G','x1']=>{:from=>'G',:to=>'x1',:arrow=>1,:label=>'G to x1', :free=>false, :value=>1.0},
|
88
|
+
['G','x2']=>{:from=>'G',:to=>'x2',:arrow=>1,:label=>'G to x2', :free=>true, :value=>nil},
|
89
|
+
['G','x3']=>{:from=>'G',:to=>'x3',:arrow=>1,:label=>'G to x3', :free=>false, :value=>1.0}
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
describe "with multiple in and outs" do
|
95
|
+
it "should set correctly 1 in, multiple outs" do
|
96
|
+
@model.path :from=>"G", :to=>['x1','x2']
|
97
|
+
@model.paths.should=={
|
98
|
+
['G','x1']=>{:from=>'G',:to=>'x1',:arrow=>1,:label=>'G to x1', :free=>true, :value=>nil},
|
99
|
+
['G','x2']=>{:from=>'G',:to=>'x2',:arrow=>1,:label=>'G to x2', :free=>true, :value=>nil}
|
100
|
+
}
|
101
|
+
end
|
102
|
+
it "should set correctly multiple ins, 1 out" do
|
103
|
+
@model.path :from=>["x1","x2"], :to=>['x3']
|
104
|
+
@model.paths.should=={
|
105
|
+
['x1','x3']=>{:from=>'x1',:to=>'x3',:arrow=>1,:label=>'x1 to x3', :free=>true, :value=>nil},
|
106
|
+
['x2','x3']=>{:from=>'x2',:to=>'x3',:arrow=>1,:label=>'x2 to x3', :free=>true, :value=>nil}
|
107
|
+
}
|
108
|
+
end
|
109
|
+
it "should set correctly multiple ins, multiples outs, with :all=>false" do
|
110
|
+
@model.path :from=>["x1","x2"], :to=>['x3','x4']
|
111
|
+
@model.paths.should=={
|
112
|
+
['x1','x3']=>{:from=>'x1',:to=>'x3',:arrow=>1,:label=>'x1 to x3', :free=>true, :value=>nil},
|
113
|
+
['x2','x4']=>{:from=>'x2',:to=>'x4',:arrow=>1,:label=>'x2 to x4', :free=>true, :value=>nil}
|
114
|
+
}
|
115
|
+
end
|
116
|
+
it "should set correctly multiple ins, multiples outs, with :all=>true" do
|
117
|
+
@model.path :from=>["x1","x2"], :to=>['x3','x4'], :all=>true
|
118
|
+
@model.paths.should=={
|
119
|
+
['x1','x3']=>{:from=>'x1',:to=>'x3',:arrow=>1,:label=>'x1 to x3', :free=>true, :value=>nil},
|
120
|
+
['x1','x4']=>{:from=>'x1',:to=>'x4',:arrow=>1,:label=>'x1 to x4', :free=>true, :value=>nil},
|
121
|
+
['x2','x3']=>{:from=>'x2',:to=>'x3',:arrow=>1,:label=>'x2 to x3', :free=>true, :value=>nil},
|
122
|
+
|
123
|
+
['x2','x4']=>{:from=>'x2',:to=>'x4',:arrow=>1,:label=>'x2 to x4', :free=>true, :value=>nil}
|
124
|
+
}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should accept a dataset" do
|
129
|
+
@model.data_from_dataset(@ds)
|
130
|
+
@model.data_type.should==:raw
|
131
|
+
@model.ds.should==@ds
|
132
|
+
@model.variables.should==@ds.fields
|
133
|
+
end
|
134
|
+
it "should accept a covariance matrix" do
|
135
|
+
@model.data_from_matrix(Statsample::Bivariate.covariance_matrix(@ds), :cases=>@ds.dup_only_valid.cases)
|
136
|
+
@model.data_type.should==:covariance
|
137
|
+
@model.cases.should==@ds.cases
|
138
|
+
@model.variables.should==@ds.fields
|
139
|
+
end
|
140
|
+
it "should accept a correlation matrix" do
|
141
|
+
@model.data_from_matrix(Statsample::Bivariate.correlation_matrix(@ds), :cases=>@ds.dup_only_valid.cases)
|
142
|
+
@model.data_type.should==:correlation
|
143
|
+
@model.cases.should==@ds.cases
|
144
|
+
@model.variables.should==@ds.fields
|
145
|
+
end
|
146
|
+
it "should duplicate correctly using 'dup'" do
|
147
|
+
@model.data_from_dataset(@ds)
|
148
|
+
@model.path :from=>"G", :to=>['x1','x2']
|
149
|
+
model2=@model.dup
|
150
|
+
model2.paths.should==@model.paths
|
151
|
+
model2.manifests.should==@model.manifests
|
152
|
+
model2.latents.should==@model.latents
|
153
|
+
model2.cases.should==@model.cases
|
154
|
+
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)+"/.")
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Statsample::SEM::OpenMxEngine do
|
5
|
+
before(:all) do
|
6
|
+
begin
|
7
|
+
@data_path=File.dirname(__FILE__)+"/fixtures/demo_open_mx.ds"
|
8
|
+
@ds=Statsample.load(@data_path)
|
9
|
+
rescue
|
10
|
+
@data_path=File.dirname(__FILE__)+"/fixtures/demo_open_mx.csv"
|
11
|
+
@ds=Statsample::CSV.read(@data_path)
|
12
|
+
end
|
13
|
+
@cov_matrix=Statsample::Bivariate.covariance_matrix(@ds)
|
14
|
+
@cases=@ds.cases
|
15
|
+
end
|
16
|
+
describe "using matrix based data" do
|
17
|
+
before(:all) do
|
18
|
+
@model=Statsample::SEM::Model.new do |m|
|
19
|
+
m.manifests @ds.fields
|
20
|
+
m.latents %w{G}
|
21
|
+
m.path :from=>m.latents, :to=>m.manifests
|
22
|
+
m.path :from=>m.manifests
|
23
|
+
m.path :from=>m.latents, :free=>false, :values=>1.0
|
24
|
+
m.data_from_matrix(@cov_matrix,:cases=>@cases)
|
25
|
+
end
|
26
|
+
@engine=Statsample::SEM::OpenMxEngine.new(@model)
|
27
|
+
end
|
28
|
+
it "should generate a valid r query" do
|
29
|
+
@engine.r_query.size.should>=0
|
30
|
+
end
|
31
|
+
it "should compute and return well formed response" do
|
32
|
+
lambda{@engine.compute}.should_not raise_error
|
33
|
+
pp @engine.r_summary
|
34
|
+
@engine.r_summary.should be_instance_of (Array)
|
35
|
+
end
|
36
|
+
it "should return a valid graphviz definition for model" do
|
37
|
+
@engine.graphviz.size.should>=0
|
38
|
+
end
|
39
|
+
it "method chi_square return X^2 of model" do
|
40
|
+
@engine.chi_square.should be_close(7.384,0.001)
|
41
|
+
end
|
42
|
+
it "method df return degrees of freedom of model" do
|
43
|
+
@engine.df.should==5
|
44
|
+
end
|
45
|
+
it "method chi_square_null return X^2 of null model" do
|
46
|
+
@engine.chi_square_null.should be_close(3725.0596,0.001)
|
47
|
+
end
|
48
|
+
it "method df_null return degrees of freedom for null model" do
|
49
|
+
@engine.df_null.should==10
|
50
|
+
end
|
51
|
+
it "method goodness_of_fit return GFI" do
|
52
|
+
pending('Not Implemented')
|
53
|
+
@engine.goodness_of_fit.should be_close(0.99426, 0.0001)
|
54
|
+
end
|
55
|
+
it "method adjusted_goodness_of_fit return AGFI" do
|
56
|
+
pending('Not Implemented')
|
57
|
+
@engine.adjusted_goodness_of_fit.should be_close(0.98277, 0.0001)
|
58
|
+
end
|
59
|
+
it "method rmsea and derivatives returns... RMSEA!" do
|
60
|
+
@engine.rmsea.should be_close(0.030911, 0.0001)
|
61
|
+
end
|
62
|
+
it "method rmsea_alpha and rmsea_confidence_interval returns alpa and ci for RMSEA" do
|
63
|
+
pending('Not Implemented other methods')
|
64
|
+
@engine.rmsea_alpha.should==0.90
|
65
|
+
@engine.rmsea_confidence_interval[0].should be_nil
|
66
|
+
@engine.rmsea_confidence_interval[1].should be_close(0.074569, 0.0001)
|
67
|
+
end
|
68
|
+
it "method nfi returns NFI" do
|
69
|
+
@engine.nfi.should be_close(0.99802, 0.0001)
|
70
|
+
end
|
71
|
+
it "method nnfi returns NNFI" do
|
72
|
+
|
73
|
+
@engine.nnfi.should be_close(0.99872, 0.0001)
|
74
|
+
end
|
75
|
+
it "method cfi returns CFI" do
|
76
|
+
@engine.cfi.should be_close(0.99936, 0.0001)
|
77
|
+
end
|
78
|
+
it "method srmr returns SRMR" do
|
79
|
+
pending('Not Implemented')
|
80
|
+
@engine.srmr.should be_close(0.0032191, 0.0001)
|
81
|
+
end
|
82
|
+
it "method bic returns BIC" do
|
83
|
+
pending("Not well implemented")
|
84
|
+
@engine.bic.should be_close(-23.689, 0.001)
|
85
|
+
end
|
86
|
+
it "method iterations returns the number of iterations" do
|
87
|
+
pending('Not Implemented')
|
88
|
+
@engine.iterations.should==30
|
89
|
+
end
|
90
|
+
|
91
|
+
# G to x1 0.397152 0.0155826 25.4869 0 x1 <--- G
|
92
|
+
# G to x2 0.503662 0.0182767 27.5576 0 x2 <--- G
|
93
|
+
# G to x3 0.577242 0.0204998 28.1584 0 x3 <--- G
|
94
|
+
# G to x4 0.702774 0.0240755 29.1905 0 x4 <--- G
|
95
|
+
# G to x5 0.796251 0.0267431 29.7741 0 x5 <--- G
|
96
|
+
# var x1 0.040814 0.0028254 14.4455 0 x1 <--> x1
|
97
|
+
# var x2 0.038020 0.0028185 13.4893 0 x2 <--> x2
|
98
|
+
# var x3 0.040827 0.0031653 12.8986 0 x3 <--> x3
|
99
|
+
# var x4 0.039387 0.0034217 11.5110 0 x4 <--> x4
|
100
|
+
# var x5 0.036287 0.0036916 9.8296 0 x5 <--> x5
|
101
|
+
it "coefficients returns a hash of Parameter estimates" do
|
102
|
+
coeffs=@engine.coefficients
|
103
|
+
coeffs[['G','x1']][:estimate].should be_close(0.397152, 0.00001)
|
104
|
+
coeffs[['G','x1']][:se].should be_close(0.0155826, 0.0001)
|
105
|
+
coeffs[['G','x1']][:label].should=='G to x1'
|
106
|
+
# pending('Not Implemented z')
|
107
|
+
# coeffs[['G','x1']][:z].should be_close(25.4869, 0.0001)
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
end
|
112
|
+
if(false)
|
113
|
+
describe "using raw data" do
|
114
|
+
before(:each) do
|
115
|
+
@model=Statsample::SEM::Model.new do |m|
|
116
|
+
m.manifests @ds.fields
|
117
|
+
m.latents %w{G}
|
118
|
+
m.path :from=>m.latents, :to=>m.manifests
|
119
|
+
m.path :from=>m.manifests
|
120
|
+
m.path :from=>m.latents, :free=>false, :values=>1.0
|
121
|
+
m.path :from=>"one", :to=>m.manifests
|
122
|
+
m.data_from_dataset(@ds)
|
123
|
+
end
|
124
|
+
@engine=Statsample::SEM::OpenMxEngine.new(@model)
|
125
|
+
end
|
126
|
+
it "should generate a valid r query" do
|
127
|
+
@engine.r_query.size.should>=0
|
128
|
+
end
|
129
|
+
it "should compute and return well formed response" do
|
130
|
+
lambda{@engine.compute}.should_not raise_error
|
131
|
+
@engine.r_summary.should be_instance_of (Array)
|
132
|
+
end
|
133
|
+
it "should return a valid graphviz definition for model" do
|
134
|
+
@engine.graphviz.should match "digraph"
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
@@ -0,0 +1,116 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)+"/.")
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Statsample::SEM::SemJFoxEngine do
|
5
|
+
before(:all) do
|
6
|
+
begin
|
7
|
+
@data_path=File.dirname(__FILE__)+"/fixtures/demo_open_mx.ds"
|
8
|
+
@ds=Statsample.load(@data_path)
|
9
|
+
rescue
|
10
|
+
@data_path=File.dirname(__FILE__)+"/fixtures/demo_open_mx.csv"
|
11
|
+
@ds=Statsample::CSV.read(@data_path)
|
12
|
+
end
|
13
|
+
@cov_matrix=Statsample::Bivariate.covariance_matrix(@ds)
|
14
|
+
@cases=@ds.cases
|
15
|
+
end
|
16
|
+
describe "using matrix based data" do
|
17
|
+
before(:all) do
|
18
|
+
@model=Statsample::SEM::Model.new do |m|
|
19
|
+
m.manifests @ds.fields
|
20
|
+
m.latents %w{G}
|
21
|
+
m.path :from=>m.latents, :to=>m.manifests
|
22
|
+
m.path :from=>m.manifests
|
23
|
+
m.path :from=>m.latents, :free=>false, :values=>1.0
|
24
|
+
m.data_from_matrix(@cov_matrix,:cases=>@cases)
|
25
|
+
end
|
26
|
+
@engine=Statsample::SEM::SemJFoxEngine.new(@model)
|
27
|
+
end
|
28
|
+
it "should generate a valid r query" do
|
29
|
+
@engine.r_query.size.should>=0
|
30
|
+
end
|
31
|
+
it "should compute and return well formed response" do
|
32
|
+
lambda{@engine.compute}.should_not raise_error
|
33
|
+
@engine.r_summary.should be_instance_of (Array)
|
34
|
+
end
|
35
|
+
it "should return a valid graphviz definition for model" do
|
36
|
+
@engine.graphviz.should match "digraph"
|
37
|
+
end
|
38
|
+
|
39
|
+
# Model Chisquare = 7.384 Df = 5 Pr(>Chisq) = 0.19361
|
40
|
+
# Chisquare (null model) = 3725.1 Df = 10
|
41
|
+
# Goodness-of-fit index = 0.99426
|
42
|
+
# Adjusted goodness-of-fit index = 0.98277
|
43
|
+
# RMSEA index = 0.030911 90% CI: (NA, 0.074569)
|
44
|
+
# Bentler-Bonnett NFI = 0.99802
|
45
|
+
# Tucker-Lewis NNFI = 0.99872
|
46
|
+
# Bentler CFI = 0.99936
|
47
|
+
# SRMR = 0.0032191
|
48
|
+
# BIC = -23.689
|
49
|
+
|
50
|
+
it "method chi_square return X^2 of model" do
|
51
|
+
@engine.chi_square.should be_close(7.384,0.001)
|
52
|
+
end
|
53
|
+
it "method df return degrees of freedom of model" do
|
54
|
+
@engine.df.should==5
|
55
|
+
end
|
56
|
+
it "method chi_square_null return X^2 of null model" do
|
57
|
+
@engine.chi_square_null.should be_close(3725.0596,0.001)
|
58
|
+
end
|
59
|
+
it "method df_null return degrees of freedom for null model" do
|
60
|
+
@engine.df_null.should==10
|
61
|
+
end
|
62
|
+
it "method goodness_of_fit return GFI" do
|
63
|
+
@engine.goodness_of_fit.should be_close(0.99426, 0.0001)
|
64
|
+
end
|
65
|
+
it "method adjusted_goodness_of_fit return AGFI" do
|
66
|
+
@engine.adjusted_goodness_of_fit.should be_close(0.98277, 0.0001)
|
67
|
+
end
|
68
|
+
it "method rmsa and derivatives returns... RMSEA!" do
|
69
|
+
@engine.rmsea.should be_close(0.030911, 0.0001)
|
70
|
+
@engine.rmsea_alpha.should==0.90
|
71
|
+
@engine.rmsea_confidence_interval[0].should be_nil
|
72
|
+
@engine.rmsea_confidence_interval[1].should be_close(0.074569, 0.0001)
|
73
|
+
end
|
74
|
+
it "method nfi returns NFI" do
|
75
|
+
@engine.nfi.should be_close(0.99802, 0.0001)
|
76
|
+
end
|
77
|
+
it "method nnfi returns NNFI" do
|
78
|
+
@engine.nnfi.should be_close(0.99872, 0.0001)
|
79
|
+
end
|
80
|
+
it "method cfi returns CFI" do
|
81
|
+
@engine.cfi.should be_close(0.99936, 0.0001)
|
82
|
+
end
|
83
|
+
it "method srmr returns SRMR" do
|
84
|
+
@engine.srmr.should be_close(0.0032191, 0.0001)
|
85
|
+
end
|
86
|
+
it "method bic returns BIC" do
|
87
|
+
@engine.bic.should be_close(-23.689, 0.001)
|
88
|
+
end
|
89
|
+
it "method iterations returns the number of iterations" do
|
90
|
+
@engine.iterations.should==30
|
91
|
+
end
|
92
|
+
|
93
|
+
# G to x1 0.397152 0.0155826 25.4869 0 x1 <--- G
|
94
|
+
# G to x2 0.503662 0.0182767 27.5576 0 x2 <--- G
|
95
|
+
# G to x3 0.577242 0.0204998 28.1584 0 x3 <--- G
|
96
|
+
# G to x4 0.702774 0.0240755 29.1905 0 x4 <--- G
|
97
|
+
# G to x5 0.796251 0.0267431 29.7741 0 x5 <--- G
|
98
|
+
# var x1 0.040814 0.0028254 14.4455 0 x1 <--> x1
|
99
|
+
# var x2 0.038020 0.0028185 13.4893 0 x2 <--> x2
|
100
|
+
# var x3 0.040827 0.0031653 12.8986 0 x3 <--> x3
|
101
|
+
# var x4 0.039387 0.0034217 11.5110 0 x4 <--> x4
|
102
|
+
# var x5 0.036287 0.0036916 9.8296 0 x5 <--> x5
|
103
|
+
it "coefficients returns a hash of Parameter estimates" do
|
104
|
+
coeffs=@engine.coefficients
|
105
|
+
coeffs[['G','x1']][:estimate].should be_close(0.397152, 0.00001)
|
106
|
+
coeffs[['G','x1']][:se].should be_close(0.0155826, 0.00001)
|
107
|
+
coeffs[['G','x1']][:z].should be_close(25.4869, 0.0001)
|
108
|
+
coeffs[['G','x1']][:label].should=='G to x1'
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
end
|
116
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)+"/.")
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Statsample::SEM do
|
5
|
+
before(:all) do
|
6
|
+
begin
|
7
|
+
@data_path=File.dirname(__FILE__)+"/fixtures/demo_open_mx.ds"
|
8
|
+
@ds=Statsample.load(@data_path)
|
9
|
+
rescue
|
10
|
+
@data_path=File.dirname(__FILE__)+"/fixtures/demo_open_mx.csv"
|
11
|
+
@ds=Statsample::CSV.read(@data_path)
|
12
|
+
end
|
13
|
+
@cov_matrix=Statsample::Bivariate.covariance_matrix(@ds)
|
14
|
+
@cases=@ds.cases
|
15
|
+
@sem=Statsample::SEM.new do |m|
|
16
|
+
m.manifests @ds.fields
|
17
|
+
m.latents %w{G}
|
18
|
+
m.path :from=>m.latents, :to=>m.manifests
|
19
|
+
m.path :from=>m.manifests
|
20
|
+
m.path :from=>m.latents, :free=>false, :values=>1.0
|
21
|
+
m.data_from_matrix(@cov_matrix,:cases=>@cases)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
it "should calculate SEM using openmx" do
|
25
|
+
@sem.engine=:openmx
|
26
|
+
@sem.name="Using OpenMx"
|
27
|
+
@sem.compute.should be_true
|
28
|
+
end
|
29
|
+
it "should calculate SEM using sem" do
|
30
|
+
@sem.engine=:sem
|
31
|
+
@sem.name="Using SEM"
|
32
|
+
@sem.compute.should be_true
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|