-
Notifications
You must be signed in to change notification settings - Fork 96
/
spss.rb
131 lines (126 loc) · 4.19 KB
/
spss.rb
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
# = spss.rb -
#
# Provides utilites for working with spss files
#
# Copyright (C) 2009 Claudio Bustos
#
# Claudio Bustos mailto:clbustos@gmail.com
module SPSS # :nodoc: all
module Dictionary
class Element
def add(a)
@elements.push(a)
end
def parse_elements(func=:to_s)
@elements.collect{|e| " "+e.send(func)}.join("\n")
end
def init_with config
config.each {|key,value|
self.send(key.to_s+"=",value) if methods.include? key.to_s
}
end
def initialize(config={})
@config=config
@elements=[]
end
end
class Dictionary < Element
attr_accessor :locale, :date_time, :row_count
def initialize(config={})
super
init_with ({
:locale=>"en_US",
:date_time=>Time.new().strftime("%Y-%m-%dT%H:%M:%S"),
:row_count=>1
})
init_with config
end
def to_xml
"<dictionary locale='#{@locale}' creationDateTime='#{@date_time}' rowCount='#{@row_count}' xmlns='http://xml.spss.com/spss/data'>\n"+parse_elements(:to_xml)+"\n</dictionary>"
end
def to_spss
parse_elements(:to_spss)
end
end
class MissingValue < Element
attr_accessor :data, :type, :from, :to
def initialize(data,type=nil)
@data=data
if type.nil? or type=="lowerBound" or type=="upperBound"
@type=type
else
raise Exception,"Incorrect value for type"
end
end
def to_xml
"<missingValue data='#{@data}' "+(type.nil? ? "":"type='#{type}'")+"/>"
end
end
class LabelSet
attr_accessor
def initialize(labels)
@labels=labels
end
def parse_xml(name)
"<valueLabelSet>\n "+@labels.collect{|key,value| "<valueLabel label='#{key}' value='#{value}' />"}.join("\n ")+"\n <valueLabelVariable name='#{name}' />\n</valueLabelSet>"
end
def parse_spss()
@labels.collect{|key,value| "#{key} '#{value}'"}.join("\n ")
end
end
class Variable < Element
attr_accessor :aligment, :display_width, :label, :measurement_level, :name, :type, :decimals, :width, :type_format, :labelset, :missing_values
def initialize(config={})
super
@@var_number||=1
init_with({
:aligment => "left",
:display_width => 8,
:label => "Variable #{@@var_number}",
:measurement_level => "SCALE",
:name => "var#{@@var_number}",
:type => 0,
:decimals => 2,
:width => 10,
:type_format => "F",
:labelset => nil
})
init_with config
@missing_values=[]
@@var_number+=1
end
def to_xml
labelset_s=(@labelset.nil?) ? "":"\n"+@labelset.parse_xml(@name)
missing_values=(@missing_values.size>0) ? @missing_values.collect {|m| m.to_xml}.join("\n"):""
"<variable aligment='#{@aligment}' displayWidth='#{@display_width}' label='#{@label}' measurementLevel='#{@measurement_level}' name='#{@name}' type='#{@type}'>\n<variableFormat decimals='#{@decimals}' width='#{@width}' type='#{@type_format}' />\n"+parse_elements(:to_xml)+missing_values+"</variable>"+labelset_s
end
def to_spss
out=<<HERE
VARIABLE LABELS #{@name} '#{label}' .
VARIABLE ALIGMENT #{@name} (#{@aligment.upcase}) .
VARIABLE WIDTH #{@name} (#{@display_width}) .
VARIABLE LEVEL #{@name} (#{@measurement_level.upcase}) .
HERE
if !@labelset.nil?
out << "VALUE LABELS #{@name} "+labelset.parse_spss()+" ."
end
if @missing_values.size>0
out << "MISSING VALUES #{@name} ("+@missing_values.collect{|m| m.data}.join(",")+") ."
end
out
end
end
end
end
n=SPSS::Dictionary::Dictionary.new
ls=SPSS::Dictionary::LabelSet.new({1=>"Si",2=>"No"})
var1=SPSS::Dictionary::Variable.new
var1.labelset=ls
mv1=SPSS::Dictionary::MissingValue.new("-99")
var2=SPSS::Dictionary::Variable.new
n.add(var1)
n.add(var2)
var2.missing_values=[mv1]
File.open("dic_spss.sps","wb") {|f|
f.puts n.to_spss
}