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

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

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:



61
62
63
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 61

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



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 81

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.



31
32
33
34
35
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 31

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



45
46
47
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 45

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)


112
113
114
115
116
117
118
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 112

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



120
121
122
123
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 120

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

#yObject



125
126
127
128
# File 'lib/spatial_stats/local/bivariate_moran.rb', line 125

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