Class: Rserve::REXP
- Inherits:
-
Object
- Object
- Rserve::REXP
- Defined in:
- lib/rserve/rexp.rb,
lib/rserve/rexp/s4.rb,
lib/rserve/rexp/raw.rb,
lib/rserve/rexp/list.rb,
lib/rserve/rexp/null.rb,
lib/rserve/rexp/double.rb,
lib/rserve/rexp/factor.rb,
lib/rserve/rexp/string.rb,
lib/rserve/rexp/symbol.rb,
lib/rserve/rexp/vector.rb,
lib/rserve/rexp/integer.rb,
lib/rserve/rexp/logical.rb,
lib/rserve/rexp/unknown.rb,
lib/rserve/rexp/wrapper.rb,
lib/rserve/rexp/function.rb,
lib/rserve/rexp/language.rb,
lib/rserve/rexp/reference.rb,
lib/rserve/rexp/environment.rb,
lib/rserve/rexp/genericvector.rb,
lib/rserve/rexp/expressionvector.rb
Overview
Basic class representing an object of any type in R. Each type in R in represented by a specific subclass. This class defines basic accessor methods (as
_xxx), type check methods (XXX?
), gives access to attributes (REXP.get_attribute, REXP.has_attribute?) as well as several convenience methods. If a given method is not applicable to a particular type, it will throw the MismatchError exception.
This root class will throw on any accessor call and returns false
for all type methods. This allows subclasses to override accessor and type methods selectively.
Defined Under Namespace
Modules: Wrapper Classes: Double, Environment, ExpressionVector, Factor, Function, GenericVector, Integer, Language, List, Logical, Null, Raw, Reference, S4, String, Symbol, Unknown, Vector
Constant Summary collapse
- MismatchError =
Class.new(StandardError)
- MaxDebugItems =
specifies how many items of a vector or list will be displayed in #toDebugString
32
Instance Attribute Summary collapse
-
#attr ⇒ Object
readonly
Returns the value of attribute attr.
Class Method Summary collapse
-
.create_data_frame(l) ⇒ Object
creates a data frame object from a list object using integer row names.
Instance Method Summary collapse
-
#as_bytes ⇒ Array
returns the contents as an array of bytes (if supported by the represented object).
-
#as_double ⇒ Float
convenience method corresponding to
as_floats[0]
. -
#as_double_matrix ⇒ Array
returns the content of the REXP as a ruby matrix of doubles (2D-array: m[cols]).
-
#as_doubles ⇒ Array
returns the contents as an array of floats (C double precision) (if supported by the represented object).
-
#as_factor ⇒ RFactor
returns the contents as a factor (if supported by the represented object).
-
#as_float ⇒ Float
Alias for as_double().
-
#as_floats ⇒ Array
On Ruby, Float are stored in double precision.
-
#as_integer ⇒ Integer
convenience method corresponding to
as_integer()[0]
. -
#as_integers ⇒ Array
returns the contents as an array of integers (if supported by the represented object).
-
#as_list ⇒ Array
returns the contents as a (named) list (if supported by the represented object).
-
#as_matrix ⇒ Matrix
Returns a standard library’s matrix.
-
#as_nested_array ⇒ Array
Returns the content of the REXP as a serie of nested arrays of X dimensions.
-
#as_string ⇒ String
convenience method corresponding to
as_strings[0]
. -
#as_strings ⇒ Array
returns the contents as an array of Strings (if supported by the represented object).
-
#complex? ⇒ boolean
check whether the
REXP
object is a complex vector. -
#dim ⇒ Object
Returns dimensions of the object (as determined by the REXP::dim() attribute).
-
#environment? ⇒ boolean
check whether the
REXP
object is an environment. -
#expression? ⇒ boolean
check whether the
REXP
object is an expression vector. -
#factor? ⇒ boolean
check whether the
REXP
object is a factor. -
#get_attribute(name) ⇒ Rlist?
Retrieve an attribute of the given name from this object.
-
#has_attribute?(name) ⇒ boolean
checks whether this object has a given attribute.
-
#inherits?(klass) ⇒ boolean
determines whether this object inherits from a given class in the same fashion as the
inherits()
function in R does (i.e. ignoring S4 inheritance). -
#initialize(attr = nil) ⇒ REXP
constructor
A new instance of REXP.
-
#integer? ⇒ boolean
check whether the
REXP
object is an integer vector. -
#language? ⇒ boolean
check whether the
REXP
object is a language object. -
#length ⇒ Integer
returns the length of a vector object.
-
#list? ⇒ boolean
check whether the
REXP
object is a list (either generic vector or a pairlist - i.e. REXP.asList() will succeed). -
#logical? ⇒ boolean
check whether the
REXP
object is a logical vector. -
#na? ⇒ boolean
returns a boolean vector of the same length as this vector with
true
for NA values andfalse
for any other values. -
#null? ⇒ boolean
check whether the
REXP
object is NULL. -
#numeric? ⇒ boolean
check whether the
REXP
object is a numeric vector. -
#pair_list? ⇒ boolean
check whether the
REXP
object is a pair-list. -
#raw? ⇒ boolean
check whether the
REXP
object is a raw vector. -
#recursive? ⇒ boolean
check whether the
REXP
object is a recursive obejct. -
#reference? ⇒ boolean
check whether the
REXP
object is a reference to an R object. -
#split_array(ar, dims) ⇒ Object
:nodoc:.
-
#string? ⇒ boolean
check whether the
REXP
object is a character vector (string). -
#symbol? ⇒ boolean
check whether the
REXP
object is a symbol. -
#to_debug_string ⇒ String
returns representation that it useful for debugging (e.g. it includes attributes and may include vector values).
-
#to_f ⇒ Float
Alias for as_float().
-
#to_i ⇒ Integer
Alias for as_integer().
-
#to_ruby ⇒ Object
Retrieves the best Ruby representation of data.
-
#to_ruby_internal ⇒ Object
Return the bare-bone representation of REXP as a Ruby Object.
-
#vector? ⇒ boolean
check whether the
REXP
object is a vector.
Constructor Details
#initialize(attr = nil) ⇒ REXP
Returns a new instance of REXP.
10 11 12 13 14 |
# File 'lib/rserve/rexp.rb', line 10 def initialize(attr=nil) # Sorry for this, but I think is necessary to maintain sanity of attributes raise ArgumentError, "Attribute should be a REXP::List, #{attr.class} provided" unless attr.nil? or attr.is_a? REXP::List @attr=attr end |
Instance Attribute Details
#attr ⇒ Object (readonly)
Returns the value of attribute attr.
9 10 11 |
# File 'lib/rserve/rexp.rb', line 9 def attr @attr end |
Class Method Details
.create_data_frame(l) ⇒ Object
creates a data frame object from a list object using integer row names.
-
@param [Rlist] a (named) list of vectors (REXP::Vector subclasses), each element corresponds to a column and all elements must have the same length.
-
@return [GenericVector] a data frame object representation.
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 |
# File 'lib/rserve/rexp.rb', line 368 def self.create_data_frame(l) raise(MismatchError, "data frame (must have dim>0)") if l.nil? or l.size<1 raise MismatchError, "data frame (contents must be vectors)" if (!(l[0].is_a? REXP::Vector)) fe = l[0] return REXP::GenericVector.new(l, REXP::List.new( Rlist.new( [ REXP::String.new("data.frame"), REXP::String.new(l.keys()), REXP::Integer.new([REXP::Integer::NA, -fe.length()]) ], ["class", "names", "row.names" ]) ) ) end |
Instance Method Details
#as_bytes ⇒ Array
returns the contents as an array of bytes (if supported by the represented object).
157 158 159 |
# File 'lib/rserve/rexp.rb', line 157 def as_bytes raise MismatchError , "byte" end |
#as_double ⇒ Float
convenience method corresponding to as_floats[0]
.
207 208 209 |
# File 'lib/rserve/rexp.rb', line 207 def as_double as_doubles[0] end |
#as_double_matrix ⇒ Array
returns the content of the REXP as a ruby matrix of doubles (2D-array: m[cols]). You could use Matrix.rows(result) to create a ruby matrix. Matrix(c.eval(“matrix(c(1,2,3,4,5,6),2,3)”).as_double_matrix());</code>
297 298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/rserve/rexp.rb', line 297 def as_double_matrix ct = as_doubles() dim = get_attribute "dim" raise MismatchError, "matrix (dim attribute missing)" if dim.nil? ds = dim.as_integers raise MismatchError, "matrix (wrong dimensionality)" if (ds.length!=2) as_nested_array #m,n = ds[0], ds[1] # R stores matrices as matrix(c(1,2,3,4),2,2) = col1:(1,2), col2:(3,4) # we need to copy everything, since we create 2d array from 1d array #r=m.times.map {|i| n.times.map {|j| ct[j*n+i]}} end |
#as_doubles ⇒ Array
returns the contents as an array of floats (C double precision) (if supported by the represented object).
142 143 144 |
# File 'lib/rserve/rexp.rb', line 142 def as_doubles raise MismatchError,"double" end |
#as_factor ⇒ RFactor
returns the contents as a factor (if supported by the represented object).
169 170 171 |
# File 'lib/rserve/rexp.rb', line 169 def as_factor raise MismatchError,"factor" end |
#as_float ⇒ Float
Alias for as_double()
213 214 215 |
# File 'lib/rserve/rexp.rb', line 213 def as_float as_double end |
#as_floats ⇒ Array
On Ruby, Float are stored in double precision.
149 150 151 |
# File 'lib/rserve/rexp.rb', line 149 def as_floats as_doubles end |
#as_integer ⇒ Integer
convenience method corresponding to as_integer()[0]
194 195 196 |
# File 'lib/rserve/rexp.rb', line 194 def as_integer as_integers[0] end |
#as_integers ⇒ Array
returns the contents as an array of integers (if supported by the represented object)
134 135 136 |
# File 'lib/rserve/rexp.rb', line 134 def as_integers raise MismatchError, "int" end |
#as_list ⇒ Array
returns the contents as a (named) list (if supported by the represented object)
163 164 165 |
# File 'lib/rserve/rexp.rb', line 163 def as_list raise MismatchError,"list" end |
#as_matrix ⇒ Matrix
Returns a standard library’s matrix.
313 314 315 316 |
# File 'lib/rserve/rexp.rb', line 313 def as_matrix require 'matrix' Matrix.rows(as_double_matrix) end |
#as_nested_array ⇒ Array
Returns the content of the REXP as a serie of nested arrays of X dimensions
320 321 322 323 324 325 326 |
# File 'lib/rserve/rexp.rb', line 320 def as_nested_array ct=as_doubles dim = get_attribute "dim" raise MismatchError, "array (dim attribute missing" if dim.nil? ds = dim.as_integers.reverse split_array(ct,ds) end |
#as_string ⇒ String
convenience method corresponding to as_strings[0]
.
225 226 227 |
# File 'lib/rserve/rexp.rb', line 225 def as_string as_strings[0] end |
#as_strings ⇒ Array
returns the contents as an array of Strings (if supported by the represented object).
127 128 129 |
# File 'lib/rserve/rexp.rb', line 127 def as_strings raise MismatchError, "String" end |
#complex? ⇒ boolean
check whether the REXP
object is a complex vector
108 109 110 |
# File 'lib/rserve/rexp.rb', line 108 def complex? false end |
#dim ⇒ Object
Returns dimensions of the object (as determined by the REXP::dim() attribute).
@return [Array] an array of integers with corresponding dimensions or <code>nil</code> if the object has no dimension attribute
254 255 256 257 258 259 260 261 |
# File 'lib/rserve/rexp.rb', line 254 def dim begin return has_attribute?("dim") ? @attr.as_list['dim'].as_integers : nil; rescue MismatchError # nothing to do end nil end |
#environment? ⇒ boolean
check whether the REXP
object is an environment.
74 75 76 |
# File 'lib/rserve/rexp.rb', line 74 def environment? false end |
#expression? ⇒ boolean
check whether the REXP
object is an expression vector.
86 87 88 |
# File 'lib/rserve/rexp.rb', line 86 def expression? false end |
#factor? ⇒ boolean
check whether the REXP
object is a factor.
49 50 51 |
# File 'lib/rserve/rexp.rb', line 49 def factor? false end |
#get_attribute(name) ⇒ Rlist?
Retrieve an attribute of the given name from this object.
236 237 238 |
# File 'lib/rserve/rexp.rb', line 236 def get_attribute(name) has_attribute?(name) ? @attr.as_list[name] : nil end |
#has_attribute?(name) ⇒ boolean
checks whether this object has a given attribute.
244 245 246 |
# File 'lib/rserve/rexp.rb', line 244 def has_attribute? (name) !@attr.nil? and @attr.list? and !@attr.as_list[name].nil? end |
#inherits?(klass) ⇒ boolean
determines whether this object inherits from a given class in the same fashion as the inherits()
function in R does (i.e. ignoring S4 inheritance).
267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/rserve/rexp.rb', line 267 def inherits?(klass) return false if (!has_attribute? "class") begin c = get_attribute("class").as_strings; if (!c.nil?) return c.any? {|v| v.equals klass} end rescue MismatchError end false end |
#integer? ⇒ boolean
check whether the REXP
object is an integer vector.
36 37 38 |
# File 'lib/rserve/rexp.rb', line 36 def integer? false end |
#language? ⇒ boolean
check whether the REXP
object is a language object.
80 81 82 |
# File 'lib/rserve/rexp.rb', line 80 def language? false end |
#length ⇒ Integer
returns the length of a vector object. Note that we use R semantics here, i.e. a matrix will have a length of m * n since it is represented by a single vector (see REXP.dim) for retrieving matrix and multidimentional-array dimensions).
176 177 178 |
# File 'lib/rserve/rexp.rb', line 176 def length raise MismatchError, "vector" end |
#list? ⇒ boolean
check whether the REXP
object is a list (either generic vector or a pairlist - i.e. REXP.asList() will succeed).
56 57 58 |
# File 'lib/rserve/rexp.rb', line 56 def list? false end |
#logical? ⇒ boolean
check whether the REXP
object is a logical vector.
68 69 70 |
# File 'lib/rserve/rexp.rb', line 68 def logical? false end |
#na? ⇒ boolean
returns a boolean vector of the same length as this vector with true
for NA values and false
for any other values.
184 185 186 |
# File 'lib/rserve/rexp.rb', line 184 def na? raise MismatchError, "vector" end |
#null? ⇒ boolean
check whether the REXP
object is NULL.
42 43 44 |
# File 'lib/rserve/rexp.rb', line 42 def null? false end |
#numeric? ⇒ boolean
check whether the REXP
object is a numeric vector.
30 31 32 |
# File 'lib/rserve/rexp.rb', line 30 def numeric? false end |
#pair_list? ⇒ boolean
check whether the REXP
object is a pair-list.
62 63 64 |
# File 'lib/rserve/rexp.rb', line 62 def pair_list? false end |
#raw? ⇒ boolean
check whether the REXP
object is a raw vector
103 104 105 |
# File 'lib/rserve/rexp.rb', line 103 def raw? false end |
#recursive? ⇒ boolean
check whether the REXP
object is a recursive obejct
113 114 115 |
# File 'lib/rserve/rexp.rb', line 113 def recursive? false end |
#reference? ⇒ boolean
check whether the REXP
object is a reference to an R object
118 119 120 |
# File 'lib/rserve/rexp.rb', line 118 def reference? false end |
#split_array(ar, dims) ⇒ Object
:nodoc:
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
# File 'lib/rserve/rexp.rb', line 328 def split_array(ar, dims) # :nodoc: #puts "#{ar} - #{dims}" if dims.size==1 raise "Improper size ar:#{ar} , dims=#{dims[0]}" if ar.size!=dims[0] return ar elsif dims.size==2 return Array.new() if dims.any? {|v| v==0} dims.reverse! # should rearrange values as R do # dims[0]=cols, dims[1]=rows if(true) out=[] ar.each_with_index {|v,i| r=(i/dims[0]).to_i; c=i%dims[0]; #p "#{r} : #{c}"; out[c*dims[1]+r]=v } #p out raise "out size should equal to ar size" if ar.size!=out.size ar=out end end dims_c=dims.dup current_dim=dims_c.shift current_size=ar.size/current_dim #puts "dims: #{dims_c} cs:#{current_size}, cd:#{current_dim}" parts=current_dim.times.map do |i| split_array(ar[i*current_size, current_size], dims_c) end parts end |
#string? ⇒ boolean
check whether the REXP
object is a character vector (string).
22 23 24 |
# File 'lib/rserve/rexp.rb', line 22 def string? false end |
#symbol? ⇒ boolean
check whether the REXP
object is a symbol.
92 93 94 |
# File 'lib/rserve/rexp.rb', line 92 def symbol? false end |
#to_debug_string ⇒ String
returns representation that it useful for debugging (e.g. it includes attributes and may include vector values)
284 285 286 |
# File 'lib/rserve/rexp.rb', line 284 def to_debug_string (!@attr.nil?) ? (("<"+@attr.to_debug_string()+">")+to_s()) : to_s end |
#to_f ⇒ Float
Alias for as_float()
219 220 221 |
# File 'lib/rserve/rexp.rb', line 219 def to_f as_double end |
#to_i ⇒ Integer
Alias for as_integer().
201 202 203 |
# File 'lib/rserve/rexp.rb', line 201 def to_i as_integers[0] end |
#to_ruby ⇒ Object
Retrieves the best Ruby representation of data
If R object has attributes, the Ruby object is extended with Rserve::WithAttributes. If R object have names, the Ruby object is extended with Rserve::WithNames and their elements can be accessed with [] using numbers and literals.
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/rserve/rexp.rb', line 390 def to_ruby v=to_ruby_internal if !v.nil? and !v.is_a? Numeric and !v.is_a? TrueClass and !v.is_a? FalseClass v.extend Rserve::WithAttributes v.attributes=attr.to_ruby unless attr.nil? if !v.attributes.nil? and v.attributes.has_name? 'names' v.attributes['names']=[v.attributes['names']] unless v.attributes['names'].is_a? Array or v.attributes['names'].nil? v.extend Rserve::WithNames v.names=v.attributes['names'] end if v.attributes and v.attributes.has_name? 'dim' and v.attributes.has_name? 'dimnames' and v.attributes['dim'].size == 2 if v.is_a? Array v.extend Rserve::With2DSizes v.sizes = v.attributes['dim'] end v.extend Rserve::With2DNames v.names = v.attributes['dimnames'].map{|dimension_names| (dimension_names.nil? or dimension_names.is_a?(Array)) ? dimension_names : [dimension_names]} end end # Hack: change attribute row.names according to spec if !attr.nil? and attr.as_list.has_name? 'class' and attr.as_list['class'].as_string=='data.frame' and (attr.as_list['row.names'].is_a?(REXP::Integer)) and attr.as_list['row.names'].as_integers[0]==REXP::Integer::NA v.attributes['row.names']=(1..(-attr.as_list['row.names'].as_integers[1])).to_a end v end |
#to_ruby_internal ⇒ Object
Return the bare-bone representation of REXP as a Ruby Object. Called by REXP.to_ruby, so shouldn’t be used directly by developers.
420 421 422 |
# File 'lib/rserve/rexp.rb', line 420 def to_ruby_internal raise "You should implement to_ruby_internal for #{self.class}" end |
#vector? ⇒ boolean
check whether the REXP
object is a vector.
98 99 100 |
# File 'lib/rserve/rexp.rb', line 98 def vector? false end |