Class: SpatialStats::Local::BivariateMoran

Inherits:
Stat
  • Object
show all
Defined in:
lib/spatial_stats/local/bivariate_moran.rb

Overview

BivariateMoran computes the local correlation between a variable x and spatially lagged variable y.

Instance Attribute Summary collapse

Attributes inherited from Stat

#field

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Stat

#crand, #expectation, #mc_bv, #variance, #x=, #y=, #z_score

Constructor Details

#initialize(scope, x_field, y_field, weights) ⇒ Moran

A new instance of BivariateMoran

Parameters:

  • scope (ActiveRecord::Relation)
  • x_field (Symbol, String)

    to query from scope

  • y_field (Symbol, String)

    to query from scope

  • weights (WeightsMatrix)

    to define relationship between observations in scope



18
19
20
21
22
23
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 18

def initialize(scope, x_field, y_field, weights)
  @scope = scope
  @x_field = x_field
  @y_field = y_field
  @weights = weights.standardize
end

Instance Attribute Details

#scopeObject

Returns the value of attribute scope.



24
25
26
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 24

def scope
  @scope
end

#weightsObject

Returns the value of attribute weights.



24
25
26
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 24

def weights
  @weights
end

#x_fieldObject

Returns the value of attribute x_field.



24
25
26
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 24

def x_field
  @x_field
end

#y_fieldObject

Returns the value of attribute y_field.



24
25
26
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 24

def y_field
  @y_field
end

Class Method Details

.from_observations(x, y, weights) ⇒ BivariateMoran

A new instance of BivariateMoran, from vector and weights.

Parameters:

  • x (Array)

    observations of dataset

  • y (Array)

    observations of dataset

  • weights (WeightsMatrix)

    to define relationships between observations

Returns:

Raises:

  • (ArgumentError)


34
35
36
37
38
39
40
41
42
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 34

def self.from_observations(x, y, weights)
  n = weights.n
  raise ArgumentError, 'Data size != weights.n' if x.size != n || y.size != n

  instance = new(nil, nil, nil, weights.standardize)
  instance.x = x
  instance.y = y
  instance
end

Instance Method Details

#mc(permutations = 99, seed = nil) ⇒ Array

Permutation test to determine a pseudo p-values of the #stat method. Shuffles y values, hold x values, recomputes #stat for each variation, then compares to the computed one. The ratio of more extreme values to permutations is returned for each observation.

Parameters:

  • permutations (Integer) (defaults to: 99)

    to run. Last digit should be 9 to produce round numbers.

  • seed (Integer) (defaults to: nil)

    used in random number generator for shuffles.

Returns:

  • (Array)

    of p-values

See Also:



79
80
81
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 79

def mc(permutations = 99, seed = nil)
  mc_bv(permutations, seed)
end

#quadsArray Also known as: groups

Determines what quadrant an observation is in. Based on its value compared to its neighbors. This does not work for all stats, since it requires that values be negative.

In a standardized array of z, high values are values greater than 0 and it’s neighbors are determined by the spatial lag and if that is positive then it’s neighbors would be high, low otherwise.

Quadrants are:

HH

a high value surrounded by other high values

LH

a low value surrounded by high values

LL

a low value surrounded by low values

HL

a high value surrounded by low values

Returns:

  • (Array)

    of labels



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 99

def quads
  # https://github.com/pysal/esda/blob/master/esda/moran.py#L925
  z_lag = SpatialStats::Utils::Lag.neighbor_average(weights, y)
  zp = x.map(&:positive?)
  lp = z_lag.map(&:positive?)

  # hh = zp & lp
  # lh = zp ^ true & lp
  # ll = zp ^ true & lp ^ true
  # hl = zp next to lp ^ true
  hh = zp.each_with_index.map { |v, idx| v & lp[idx] }
  lh = zp.each_with_index.map { |v, idx| (v ^ true) & lp[idx] }
  ll = zp.each_with_index.map { |v, idx| (v ^ true) & (lp[idx] ^ true) }
  hl = zp.each_with_index.map { |v, idx| v & (lp[idx] ^ true) }

  # now zip lists and map them to proper terms
  quad_terms = %w[HH LH LL HL]
  hh.zip(lh, ll, hl).map do |feature|
    quad_terms[feature.index(true)]
  end
end

#statArray Also known as: i

Computes the local indicator of spatial correlation for x against lagged y.

Returns:

  • (Array)

    of correlations for each observation.



49
50
51
52
53
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 49

def stat
  x.each_with_index.map do |_xi, idx|
    stat_i(idx)
  end
end

#stat_i(idx) ⇒ Float

Computes Bivariate Moran’s I at a single index. Multiplies x at this index by the lagged y value at this index.

Parameters:

  • idx (Integer)

    to perfrom the calculation on

Returns:

  • (Float)

    correlation at idx



63
64
65
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 63

def stat_i(idx)
  x[idx] * y_lag[idx]
end

#summary(permutations = 99, seed = nil) ⇒ Array

Summary of the statistic. Computes stat, mc, and groups then returns the values in a hash array.

Parameters:

  • permutations (Integer) (defaults to: 99)

    to run. Last digit should be 9 to produce round numbers.

  • seed (Integer) (defaults to: nil)

    used in random number generator for shuffles.

Returns:

  • (Array)


130
131
132
133
134
135
136
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 130

def summary(permutations = 99, seed = nil)
  p_vals = mc(permutations, seed)
  data = weights.keys.zip(stat, p_vals, groups)
  data.map do |row|
    { key: row[0], stat: row[1], p: row[2], group: row[3] }
  end
end

#xObject



138
139
140
141
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 138

def x
  @x ||= SpatialStats::Queries::Variables.query_field(@scope, @x_field)
                                         .standardize
end

#yObject



143
144
145
146
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 143

def y
  @y ||= SpatialStats::Queries::Variables.query_field(@scope, @y_field)
                                         .standardize
end