@turf/moran-index 7.0.0-alpha.0 → 7.0.0-alpha.110
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.
- package/README.md +4 -9
- package/dist/cjs/index.cjs +82 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/{js → cjs}/index.d.ts +5 -9
- package/dist/esm/index.d.mts +59 -0
- package/dist/esm/index.mjs +82 -0
- package/dist/esm/index.mjs.map +1 -0
- package/package.json +33 -27
- package/dist/es/index.js +0 -131
- package/dist/es/package.json +0 -1
- package/dist/js/index.js +0 -135
package/README.md
CHANGED
|
@@ -100,26 +100,21 @@ Type: [Object][4]
|
|
|
100
100
|
|
|
101
101
|
[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
|
|
102
102
|
|
|
103
|
-
<!-- This file is automatically generated. Please don't edit it directly
|
|
104
|
-
if you find an error, edit the source file (likely index.js), and re-run
|
|
105
|
-
./scripts/generate-readmes in the turf project. -->
|
|
103
|
+
<!-- This file is automatically generated. Please don't edit it directly. If you find an error, edit the source file of the module in question (likely index.js or index.ts), and re-run "yarn docs" from the root of the turf project. -->
|
|
106
104
|
|
|
107
105
|
---
|
|
108
106
|
|
|
109
|
-
This module is part of the [Turfjs project](
|
|
110
|
-
module collection dedicated to geographic algorithms. It is maintained in the
|
|
111
|
-
[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create
|
|
112
|
-
PRs and issues.
|
|
107
|
+
This module is part of the [Turfjs project](https://turfjs.org/), an open source module collection dedicated to geographic algorithms. It is maintained in the [Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create PRs and issues.
|
|
113
108
|
|
|
114
109
|
### Installation
|
|
115
110
|
|
|
116
|
-
Install this module individually:
|
|
111
|
+
Install this single module individually:
|
|
117
112
|
|
|
118
113
|
```sh
|
|
119
114
|
$ npm install @turf/moran-index
|
|
120
115
|
```
|
|
121
116
|
|
|
122
|
-
Or install the
|
|
117
|
+
Or install the all-encompassing @turf/turf module that includes all modules as functions:
|
|
123
118
|
|
|
124
119
|
```sh
|
|
125
120
|
$ npm install @turf/turf
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// index.ts
|
|
5
|
+
var _distanceweight = require('@turf/distance-weight');
|
|
6
|
+
var _meta = require('@turf/meta');
|
|
7
|
+
function moranIndex(fc, options) {
|
|
8
|
+
var _a, _b;
|
|
9
|
+
const inputField = options.inputField;
|
|
10
|
+
const threshold = options.threshold || 1e5;
|
|
11
|
+
const p = options.p || 2;
|
|
12
|
+
const binary = (_a = options.binary) != null ? _a : false;
|
|
13
|
+
const alpha = options.alpha || -1;
|
|
14
|
+
const standardization = (_b = options.standardization) != null ? _b : true;
|
|
15
|
+
const weight = _distanceweight.distanceWeight.call(void 0, fc, {
|
|
16
|
+
alpha,
|
|
17
|
+
binary,
|
|
18
|
+
p,
|
|
19
|
+
standardization,
|
|
20
|
+
threshold
|
|
21
|
+
});
|
|
22
|
+
const y = [];
|
|
23
|
+
_meta.featureEach.call(void 0, fc, (feature) => {
|
|
24
|
+
const feaProperties = feature.properties || {};
|
|
25
|
+
y.push(feaProperties[inputField]);
|
|
26
|
+
});
|
|
27
|
+
const yMean = mean(y);
|
|
28
|
+
const yVar = variance(y);
|
|
29
|
+
let weightSum = 0;
|
|
30
|
+
let s0 = 0;
|
|
31
|
+
let s1 = 0;
|
|
32
|
+
let s2 = 0;
|
|
33
|
+
const n = weight.length;
|
|
34
|
+
for (let i = 0; i < n; i++) {
|
|
35
|
+
let subS2 = 0;
|
|
36
|
+
for (let j = 0; j < n; j++) {
|
|
37
|
+
weightSum += weight[i][j] * (y[i] - yMean) * (y[j] - yMean);
|
|
38
|
+
s0 += weight[i][j];
|
|
39
|
+
s1 += Math.pow(weight[i][j] + weight[j][i], 2);
|
|
40
|
+
subS2 += weight[i][j] + weight[j][i];
|
|
41
|
+
}
|
|
42
|
+
s2 += Math.pow(subS2, 2);
|
|
43
|
+
}
|
|
44
|
+
s1 = 0.5 * s1;
|
|
45
|
+
const moranIndex2 = weightSum / s0 / yVar;
|
|
46
|
+
const expectedMoranIndex = -1 / (n - 1);
|
|
47
|
+
const vNum = n * n * s1 - n * s2 + 3 * (s0 * s0);
|
|
48
|
+
const vDen = (n - 1) * (n + 1) * (s0 * s0);
|
|
49
|
+
const vNorm = vNum / vDen - expectedMoranIndex * expectedMoranIndex;
|
|
50
|
+
const stdNorm = Math.sqrt(vNorm);
|
|
51
|
+
const zNorm = (moranIndex2 - expectedMoranIndex) / stdNorm;
|
|
52
|
+
return {
|
|
53
|
+
expectedMoranIndex,
|
|
54
|
+
moranIndex: moranIndex2,
|
|
55
|
+
stdNorm,
|
|
56
|
+
zNorm
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
__name(moranIndex, "moranIndex");
|
|
60
|
+
function mean(y) {
|
|
61
|
+
let sum = 0;
|
|
62
|
+
for (const item of y) {
|
|
63
|
+
sum += item;
|
|
64
|
+
}
|
|
65
|
+
return sum / y.length;
|
|
66
|
+
}
|
|
67
|
+
__name(mean, "mean");
|
|
68
|
+
function variance(y) {
|
|
69
|
+
const yMean = mean(y);
|
|
70
|
+
let sum = 0;
|
|
71
|
+
for (const item of y) {
|
|
72
|
+
sum += Math.pow(item - yMean, 2);
|
|
73
|
+
}
|
|
74
|
+
return sum / y.length;
|
|
75
|
+
}
|
|
76
|
+
__name(variance, "variance");
|
|
77
|
+
var turf_moran_index_default = moranIndex;
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
exports.default = turf_moran_index_default; exports.moranIndex = moranIndex;
|
|
82
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../index.ts"],"names":["moranIndex"],"mappings":";;;;AACA,SAAS,kBAAkB,qBAAqB;AAChD,SAAS,mBAAmB;AA6C5B,SAAS,WACP,IACA,SAaA;AA9DF;AA+DE,QAAM,aAAa,QAAQ;AAC3B,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,IAAI,QAAQ,KAAK;AACvB,QAAM,UAAS,aAAQ,WAAR,YAAkB;AACjC,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,mBAAkB,aAAQ,oBAAR,YAA2B;AAEnD,QAAM,SAAS,cAAc,IAAI;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,IAAc,CAAC;AACrB,cAAY,IAAI,CAAC,YAAY;AAC3B,UAAM,gBAAgB,QAAQ,cAAc,CAAC;AAE7C,MAAE,KAAK,cAAc,UAAU,CAAC;AAAA,EAClC,CAAC;AAED,QAAM,QAAQ,KAAK,CAAC;AACpB,QAAM,OAAO,SAAS,CAAC;AACvB,MAAI,YAAY;AAChB,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,KAAK;AACT,QAAM,IAAI,OAAO;AAEjB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,QAAI,QAAQ;AACZ,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,mBAAa,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,IAAI;AACrD,YAAM,OAAO,CAAC,EAAE,CAAC;AACjB,YAAM,KAAK,IAAI,OAAO,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC;AAC7C,eAAS,OAAO,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC;AAAA,IACrC;AACA,UAAM,KAAK,IAAI,OAAO,CAAC;AAAA,EACzB;AACA,OAAK,MAAM;AAEX,QAAMA,cAAa,YAAY,KAAK;AACpC,QAAM,qBAAqB,MAAM,IAAI;AACrC,QAAM,OAAO,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK;AAC7C,QAAM,QAAQ,IAAI,MAAM,IAAI,MAAM,KAAK;AACvC,QAAM,QAAQ,OAAO,OAAO,qBAAqB;AACjD,QAAM,UAAU,KAAK,KAAK,KAAK;AAC/B,QAAM,SAASA,cAAa,sBAAsB;AAElD,SAAO;AAAA,IACL;AAAA,IACA,YAAAA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAxES;AAgFT,SAAS,KAAK,GAAqB;AACjC,MAAI,MAAM;AACV,aAAW,QAAQ,GAAG;AACpB,WAAO;AAAA,EACT;AACA,SAAO,MAAM,EAAE;AACjB;AANS;AAaT,SAAS,SAAS,GAAqB;AACrC,QAAM,QAAQ,KAAK,CAAC;AACpB,MAAI,MAAM;AACV,aAAW,QAAQ,GAAG;AACpB,WAAO,KAAK,IAAI,OAAO,OAAO,CAAC;AAAA,EACjC;AACA,SAAO,MAAM,EAAE;AACjB;AAPS;AAkBT,IAAO,2BAAQ","sourcesContent":["import { FeatureCollection } from \"geojson\";\nimport { distanceWeight as spatialWeight } from \"@turf/distance-weight\";\nimport { featureEach } from \"@turf/meta\";\n\n/**\n * Moran's I measures patterns of attribute values associated with features.\n * The method reveal whether similar values tend to occur near each other,\n * or whether high or low values are interspersed.\n *\n * Moran's I > 0 means a clusterd pattern.\n * Moran's I < 0 means a dispersed pattern.\n * Moran's I = 0 means a random pattern.\n *\n * In order to test the significance of the result. The z score is calculated.\n * A positive enough z-score (ex. >1.96) indicates clustering,\n * while a negative enough z-score (ex. <-1.96) indicates a dispersed pattern.\n *\n * the z-score can be calculated based on a normal or random assumption.\n *\n * **Bibliography***\n *\n * 1. [Moran's I](https://en.wikipedia.org/wiki/Moran%27s_I)\n *\n * 2. [pysal](http://pysal.readthedocs.io/en/latest/index.html)\n *\n * 3. Andy Mitchell, The ESRI Guide to GIS Analysis Volume 2: Spatial Measurements & Statistics.\n *\n * @name moranIndex\n * @param {FeatureCollection<any>} fc\n * @param {Object} options\n * @param {string} options.inputField the property name, must contain numeric values\n * @param {number} [options.threshold=100000] the distance threshold\n * @param {number} [options.p=2] the Minkowski p-norm distance parameter\n * @param {boolean} [options.binary=false] whether transfrom the distance to binary\n * @param {number} [options.alpha=-1] the distance decay parameter\n * @param {boolean} [options.standardization=true] wheter row standardization the distance\n * @returns {MoranIndex}\n * @example\n *\n * const bbox = [-65, 40, -63, 42];\n * const dataset = turf.randomPoint(100, { bbox: bbox });\n *\n * const result = turf.moranIndex(dataset, {\n * inputField: 'CRIME',\n * });\n */\n\nfunction moranIndex(\n fc: FeatureCollection<any>,\n options: {\n inputField: string;\n threshold?: number;\n p?: number;\n binary?: boolean;\n alpha?: number;\n standardization?: boolean;\n }\n): {\n moranIndex: number;\n expectedMoranIndex: number;\n stdNorm: number;\n zNorm: number;\n} {\n const inputField = options.inputField;\n const threshold = options.threshold || 100000;\n const p = options.p || 2;\n const binary = options.binary ?? false;\n const alpha = options.alpha || -1;\n const standardization = options.standardization ?? true;\n\n const weight = spatialWeight(fc, {\n alpha,\n binary,\n p,\n standardization,\n threshold,\n });\n\n const y: number[] = [];\n featureEach(fc, (feature) => {\n const feaProperties = feature.properties || {};\n // validate inputField exists\n y.push(feaProperties[inputField]);\n });\n\n const yMean = mean(y);\n const yVar = variance(y);\n let weightSum = 0;\n let s0 = 0;\n let s1 = 0;\n let s2 = 0;\n const n = weight.length;\n // validate y.length is the same as weight.length\n for (let i = 0; i < n; i++) {\n let subS2 = 0;\n for (let j = 0; j < n; j++) {\n weightSum += weight[i][j] * (y[i] - yMean) * (y[j] - yMean);\n s0 += weight[i][j];\n s1 += Math.pow(weight[i][j] + weight[j][i], 2);\n subS2 += weight[i][j] + weight[j][i];\n }\n s2 += Math.pow(subS2, 2);\n }\n s1 = 0.5 * s1;\n\n const moranIndex = weightSum / s0 / yVar;\n const expectedMoranIndex = -1 / (n - 1);\n const vNum = n * n * s1 - n * s2 + 3 * (s0 * s0);\n const vDen = (n - 1) * (n + 1) * (s0 * s0);\n const vNorm = vNum / vDen - expectedMoranIndex * expectedMoranIndex;\n const stdNorm = Math.sqrt(vNorm);\n const zNorm = (moranIndex - expectedMoranIndex) / stdNorm;\n\n return {\n expectedMoranIndex,\n moranIndex,\n stdNorm,\n zNorm,\n };\n}\n\n/**\n * get mean of a list\n * @param {number[]} y\n * @returns {number}\n *\n */\nfunction mean(y: number[]): number {\n let sum = 0;\n for (const item of y) {\n sum += item;\n }\n return sum / y.length;\n}\n/**\n * get variance of a list\n * @param {number[]} y\n * @returns {number}\n *\n */\nfunction variance(y: number[]): number {\n const yMean = mean(y);\n let sum = 0;\n for (const item of y) {\n sum += Math.pow(item - yMean, 2);\n }\n return sum / y.length;\n}\n\n/**\n * @typedef {Object} MoranIndex\n * @property {number} moranIndex the moran's Index of the observed feature set\n * @property {number} expectedMoranIndex the moran's Index of the random distribution\n * @property {number} stdNorm the standard devitaion of the random distribution\n * @property {number} zNorm the z-score of the observe samples with regard to the random distribution\n */\n\nexport { moranIndex };\nexport default moranIndex;\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { FeatureCollection } from
|
|
1
|
+
import { FeatureCollection } from 'geojson';
|
|
2
|
+
|
|
2
3
|
/**
|
|
3
4
|
* Moran's I measures patterns of attribute values associated with features.
|
|
4
5
|
* The method reveal whether similar values tend to occur near each other,
|
|
@@ -41,7 +42,7 @@ import { FeatureCollection } from "geojson";
|
|
|
41
42
|
* inputField: 'CRIME',
|
|
42
43
|
* });
|
|
43
44
|
*/
|
|
44
|
-
|
|
45
|
+
declare function moranIndex(fc: FeatureCollection<any>, options: {
|
|
45
46
|
inputField: string;
|
|
46
47
|
threshold?: number;
|
|
47
48
|
p?: number;
|
|
@@ -54,10 +55,5 @@ export default function (fc: FeatureCollection<any>, options: {
|
|
|
54
55
|
stdNorm: number;
|
|
55
56
|
zNorm: number;
|
|
56
57
|
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
* @property {number} moranIndex the moran's Index of the observed feature set
|
|
60
|
-
* @property {number} expectedMoranIndex the moran's Index of the random distribution
|
|
61
|
-
* @property {number} stdNorm the standard devitaion of the random distribution
|
|
62
|
-
* @property {number} zNorm the z-score of the observe samples with regard to the random distribution
|
|
63
|
-
*/
|
|
58
|
+
|
|
59
|
+
export { moranIndex as default, moranIndex };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { FeatureCollection } from 'geojson';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Moran's I measures patterns of attribute values associated with features.
|
|
5
|
+
* The method reveal whether similar values tend to occur near each other,
|
|
6
|
+
* or whether high or low values are interspersed.
|
|
7
|
+
*
|
|
8
|
+
* Moran's I > 0 means a clusterd pattern.
|
|
9
|
+
* Moran's I < 0 means a dispersed pattern.
|
|
10
|
+
* Moran's I = 0 means a random pattern.
|
|
11
|
+
*
|
|
12
|
+
* In order to test the significance of the result. The z score is calculated.
|
|
13
|
+
* A positive enough z-score (ex. >1.96) indicates clustering,
|
|
14
|
+
* while a negative enough z-score (ex. <-1.96) indicates a dispersed pattern.
|
|
15
|
+
*
|
|
16
|
+
* the z-score can be calculated based on a normal or random assumption.
|
|
17
|
+
*
|
|
18
|
+
* **Bibliography***
|
|
19
|
+
*
|
|
20
|
+
* 1. [Moran's I](https://en.wikipedia.org/wiki/Moran%27s_I)
|
|
21
|
+
*
|
|
22
|
+
* 2. [pysal](http://pysal.readthedocs.io/en/latest/index.html)
|
|
23
|
+
*
|
|
24
|
+
* 3. Andy Mitchell, The ESRI Guide to GIS Analysis Volume 2: Spatial Measurements & Statistics.
|
|
25
|
+
*
|
|
26
|
+
* @name moranIndex
|
|
27
|
+
* @param {FeatureCollection<any>} fc
|
|
28
|
+
* @param {Object} options
|
|
29
|
+
* @param {string} options.inputField the property name, must contain numeric values
|
|
30
|
+
* @param {number} [options.threshold=100000] the distance threshold
|
|
31
|
+
* @param {number} [options.p=2] the Minkowski p-norm distance parameter
|
|
32
|
+
* @param {boolean} [options.binary=false] whether transfrom the distance to binary
|
|
33
|
+
* @param {number} [options.alpha=-1] the distance decay parameter
|
|
34
|
+
* @param {boolean} [options.standardization=true] wheter row standardization the distance
|
|
35
|
+
* @returns {MoranIndex}
|
|
36
|
+
* @example
|
|
37
|
+
*
|
|
38
|
+
* const bbox = [-65, 40, -63, 42];
|
|
39
|
+
* const dataset = turf.randomPoint(100, { bbox: bbox });
|
|
40
|
+
*
|
|
41
|
+
* const result = turf.moranIndex(dataset, {
|
|
42
|
+
* inputField: 'CRIME',
|
|
43
|
+
* });
|
|
44
|
+
*/
|
|
45
|
+
declare function moranIndex(fc: FeatureCollection<any>, options: {
|
|
46
|
+
inputField: string;
|
|
47
|
+
threshold?: number;
|
|
48
|
+
p?: number;
|
|
49
|
+
binary?: boolean;
|
|
50
|
+
alpha?: number;
|
|
51
|
+
standardization?: boolean;
|
|
52
|
+
}): {
|
|
53
|
+
moranIndex: number;
|
|
54
|
+
expectedMoranIndex: number;
|
|
55
|
+
stdNorm: number;
|
|
56
|
+
zNorm: number;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export { moranIndex as default, moranIndex };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// index.ts
|
|
5
|
+
import { distanceWeight as spatialWeight } from "@turf/distance-weight";
|
|
6
|
+
import { featureEach } from "@turf/meta";
|
|
7
|
+
function moranIndex(fc, options) {
|
|
8
|
+
var _a, _b;
|
|
9
|
+
const inputField = options.inputField;
|
|
10
|
+
const threshold = options.threshold || 1e5;
|
|
11
|
+
const p = options.p || 2;
|
|
12
|
+
const binary = (_a = options.binary) != null ? _a : false;
|
|
13
|
+
const alpha = options.alpha || -1;
|
|
14
|
+
const standardization = (_b = options.standardization) != null ? _b : true;
|
|
15
|
+
const weight = spatialWeight(fc, {
|
|
16
|
+
alpha,
|
|
17
|
+
binary,
|
|
18
|
+
p,
|
|
19
|
+
standardization,
|
|
20
|
+
threshold
|
|
21
|
+
});
|
|
22
|
+
const y = [];
|
|
23
|
+
featureEach(fc, (feature) => {
|
|
24
|
+
const feaProperties = feature.properties || {};
|
|
25
|
+
y.push(feaProperties[inputField]);
|
|
26
|
+
});
|
|
27
|
+
const yMean = mean(y);
|
|
28
|
+
const yVar = variance(y);
|
|
29
|
+
let weightSum = 0;
|
|
30
|
+
let s0 = 0;
|
|
31
|
+
let s1 = 0;
|
|
32
|
+
let s2 = 0;
|
|
33
|
+
const n = weight.length;
|
|
34
|
+
for (let i = 0; i < n; i++) {
|
|
35
|
+
let subS2 = 0;
|
|
36
|
+
for (let j = 0; j < n; j++) {
|
|
37
|
+
weightSum += weight[i][j] * (y[i] - yMean) * (y[j] - yMean);
|
|
38
|
+
s0 += weight[i][j];
|
|
39
|
+
s1 += Math.pow(weight[i][j] + weight[j][i], 2);
|
|
40
|
+
subS2 += weight[i][j] + weight[j][i];
|
|
41
|
+
}
|
|
42
|
+
s2 += Math.pow(subS2, 2);
|
|
43
|
+
}
|
|
44
|
+
s1 = 0.5 * s1;
|
|
45
|
+
const moranIndex2 = weightSum / s0 / yVar;
|
|
46
|
+
const expectedMoranIndex = -1 / (n - 1);
|
|
47
|
+
const vNum = n * n * s1 - n * s2 + 3 * (s0 * s0);
|
|
48
|
+
const vDen = (n - 1) * (n + 1) * (s0 * s0);
|
|
49
|
+
const vNorm = vNum / vDen - expectedMoranIndex * expectedMoranIndex;
|
|
50
|
+
const stdNorm = Math.sqrt(vNorm);
|
|
51
|
+
const zNorm = (moranIndex2 - expectedMoranIndex) / stdNorm;
|
|
52
|
+
return {
|
|
53
|
+
expectedMoranIndex,
|
|
54
|
+
moranIndex: moranIndex2,
|
|
55
|
+
stdNorm,
|
|
56
|
+
zNorm
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
__name(moranIndex, "moranIndex");
|
|
60
|
+
function mean(y) {
|
|
61
|
+
let sum = 0;
|
|
62
|
+
for (const item of y) {
|
|
63
|
+
sum += item;
|
|
64
|
+
}
|
|
65
|
+
return sum / y.length;
|
|
66
|
+
}
|
|
67
|
+
__name(mean, "mean");
|
|
68
|
+
function variance(y) {
|
|
69
|
+
const yMean = mean(y);
|
|
70
|
+
let sum = 0;
|
|
71
|
+
for (const item of y) {
|
|
72
|
+
sum += Math.pow(item - yMean, 2);
|
|
73
|
+
}
|
|
74
|
+
return sum / y.length;
|
|
75
|
+
}
|
|
76
|
+
__name(variance, "variance");
|
|
77
|
+
var turf_moran_index_default = moranIndex;
|
|
78
|
+
export {
|
|
79
|
+
turf_moran_index_default as default,
|
|
80
|
+
moranIndex
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../index.ts"],"sourcesContent":["import { FeatureCollection } from \"geojson\";\nimport { distanceWeight as spatialWeight } from \"@turf/distance-weight\";\nimport { featureEach } from \"@turf/meta\";\n\n/**\n * Moran's I measures patterns of attribute values associated with features.\n * The method reveal whether similar values tend to occur near each other,\n * or whether high or low values are interspersed.\n *\n * Moran's I > 0 means a clusterd pattern.\n * Moran's I < 0 means a dispersed pattern.\n * Moran's I = 0 means a random pattern.\n *\n * In order to test the significance of the result. The z score is calculated.\n * A positive enough z-score (ex. >1.96) indicates clustering,\n * while a negative enough z-score (ex. <-1.96) indicates a dispersed pattern.\n *\n * the z-score can be calculated based on a normal or random assumption.\n *\n * **Bibliography***\n *\n * 1. [Moran's I](https://en.wikipedia.org/wiki/Moran%27s_I)\n *\n * 2. [pysal](http://pysal.readthedocs.io/en/latest/index.html)\n *\n * 3. Andy Mitchell, The ESRI Guide to GIS Analysis Volume 2: Spatial Measurements & Statistics.\n *\n * @name moranIndex\n * @param {FeatureCollection<any>} fc\n * @param {Object} options\n * @param {string} options.inputField the property name, must contain numeric values\n * @param {number} [options.threshold=100000] the distance threshold\n * @param {number} [options.p=2] the Minkowski p-norm distance parameter\n * @param {boolean} [options.binary=false] whether transfrom the distance to binary\n * @param {number} [options.alpha=-1] the distance decay parameter\n * @param {boolean} [options.standardization=true] wheter row standardization the distance\n * @returns {MoranIndex}\n * @example\n *\n * const bbox = [-65, 40, -63, 42];\n * const dataset = turf.randomPoint(100, { bbox: bbox });\n *\n * const result = turf.moranIndex(dataset, {\n * inputField: 'CRIME',\n * });\n */\n\nfunction moranIndex(\n fc: FeatureCollection<any>,\n options: {\n inputField: string;\n threshold?: number;\n p?: number;\n binary?: boolean;\n alpha?: number;\n standardization?: boolean;\n }\n): {\n moranIndex: number;\n expectedMoranIndex: number;\n stdNorm: number;\n zNorm: number;\n} {\n const inputField = options.inputField;\n const threshold = options.threshold || 100000;\n const p = options.p || 2;\n const binary = options.binary ?? false;\n const alpha = options.alpha || -1;\n const standardization = options.standardization ?? true;\n\n const weight = spatialWeight(fc, {\n alpha,\n binary,\n p,\n standardization,\n threshold,\n });\n\n const y: number[] = [];\n featureEach(fc, (feature) => {\n const feaProperties = feature.properties || {};\n // validate inputField exists\n y.push(feaProperties[inputField]);\n });\n\n const yMean = mean(y);\n const yVar = variance(y);\n let weightSum = 0;\n let s0 = 0;\n let s1 = 0;\n let s2 = 0;\n const n = weight.length;\n // validate y.length is the same as weight.length\n for (let i = 0; i < n; i++) {\n let subS2 = 0;\n for (let j = 0; j < n; j++) {\n weightSum += weight[i][j] * (y[i] - yMean) * (y[j] - yMean);\n s0 += weight[i][j];\n s1 += Math.pow(weight[i][j] + weight[j][i], 2);\n subS2 += weight[i][j] + weight[j][i];\n }\n s2 += Math.pow(subS2, 2);\n }\n s1 = 0.5 * s1;\n\n const moranIndex = weightSum / s0 / yVar;\n const expectedMoranIndex = -1 / (n - 1);\n const vNum = n * n * s1 - n * s2 + 3 * (s0 * s0);\n const vDen = (n - 1) * (n + 1) * (s0 * s0);\n const vNorm = vNum / vDen - expectedMoranIndex * expectedMoranIndex;\n const stdNorm = Math.sqrt(vNorm);\n const zNorm = (moranIndex - expectedMoranIndex) / stdNorm;\n\n return {\n expectedMoranIndex,\n moranIndex,\n stdNorm,\n zNorm,\n };\n}\n\n/**\n * get mean of a list\n * @param {number[]} y\n * @returns {number}\n *\n */\nfunction mean(y: number[]): number {\n let sum = 0;\n for (const item of y) {\n sum += item;\n }\n return sum / y.length;\n}\n/**\n * get variance of a list\n * @param {number[]} y\n * @returns {number}\n *\n */\nfunction variance(y: number[]): number {\n const yMean = mean(y);\n let sum = 0;\n for (const item of y) {\n sum += Math.pow(item - yMean, 2);\n }\n return sum / y.length;\n}\n\n/**\n * @typedef {Object} MoranIndex\n * @property {number} moranIndex the moran's Index of the observed feature set\n * @property {number} expectedMoranIndex the moran's Index of the random distribution\n * @property {number} stdNorm the standard devitaion of the random distribution\n * @property {number} zNorm the z-score of the observe samples with regard to the random distribution\n */\n\nexport { moranIndex };\nexport default moranIndex;\n"],"mappings":";;;;AACA,SAAS,kBAAkB,qBAAqB;AAChD,SAAS,mBAAmB;AA6C5B,SAAS,WACP,IACA,SAaA;AA9DF;AA+DE,QAAM,aAAa,QAAQ;AAC3B,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,IAAI,QAAQ,KAAK;AACvB,QAAM,UAAS,aAAQ,WAAR,YAAkB;AACjC,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,mBAAkB,aAAQ,oBAAR,YAA2B;AAEnD,QAAM,SAAS,cAAc,IAAI;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,IAAc,CAAC;AACrB,cAAY,IAAI,CAAC,YAAY;AAC3B,UAAM,gBAAgB,QAAQ,cAAc,CAAC;AAE7C,MAAE,KAAK,cAAc,UAAU,CAAC;AAAA,EAClC,CAAC;AAED,QAAM,QAAQ,KAAK,CAAC;AACpB,QAAM,OAAO,SAAS,CAAC;AACvB,MAAI,YAAY;AAChB,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,KAAK;AACT,QAAM,IAAI,OAAO;AAEjB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,QAAI,QAAQ;AACZ,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,mBAAa,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,IAAI;AACrD,YAAM,OAAO,CAAC,EAAE,CAAC;AACjB,YAAM,KAAK,IAAI,OAAO,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC;AAC7C,eAAS,OAAO,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC;AAAA,IACrC;AACA,UAAM,KAAK,IAAI,OAAO,CAAC;AAAA,EACzB;AACA,OAAK,MAAM;AAEX,QAAMA,cAAa,YAAY,KAAK;AACpC,QAAM,qBAAqB,MAAM,IAAI;AACrC,QAAM,OAAO,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK;AAC7C,QAAM,QAAQ,IAAI,MAAM,IAAI,MAAM,KAAK;AACvC,QAAM,QAAQ,OAAO,OAAO,qBAAqB;AACjD,QAAM,UAAU,KAAK,KAAK,KAAK;AAC/B,QAAM,SAASA,cAAa,sBAAsB;AAElD,SAAO;AAAA,IACL;AAAA,IACA,YAAAA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAxES;AAgFT,SAAS,KAAK,GAAqB;AACjC,MAAI,MAAM;AACV,aAAW,QAAQ,GAAG;AACpB,WAAO;AAAA,EACT;AACA,SAAO,MAAM,EAAE;AACjB;AANS;AAaT,SAAS,SAAS,GAAqB;AACrC,QAAM,QAAQ,KAAK,CAAC;AACpB,MAAI,MAAM;AACV,aAAW,QAAQ,GAAG;AACpB,WAAO,KAAK,IAAI,OAAO,OAAO,CAAC;AAAA,EACjC;AACA,SAAO,MAAM,EAAE;AACjB;AAPS;AAkBT,IAAO,2BAAQ;","names":["moranIndex"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turf/moran-index",
|
|
3
|
-
"version": "7.0.0-alpha.
|
|
3
|
+
"version": "7.0.0-alpha.110+1411d63a7",
|
|
4
4
|
"description": "turf moran-index module",
|
|
5
5
|
"author": "Turf Authors",
|
|
6
6
|
"contributors": [
|
|
@@ -23,45 +23,51 @@
|
|
|
23
23
|
"turf",
|
|
24
24
|
"moran-index"
|
|
25
25
|
],
|
|
26
|
-
"
|
|
27
|
-
"
|
|
26
|
+
"type": "commonjs",
|
|
27
|
+
"main": "dist/cjs/index.cjs",
|
|
28
|
+
"module": "dist/esm/index.mjs",
|
|
29
|
+
"types": "dist/cjs/index.d.ts",
|
|
28
30
|
"exports": {
|
|
29
31
|
"./package.json": "./package.json",
|
|
30
32
|
".": {
|
|
31
|
-
"import":
|
|
32
|
-
|
|
33
|
+
"import": {
|
|
34
|
+
"types": "./dist/esm/index.d.mts",
|
|
35
|
+
"default": "./dist/esm/index.mjs"
|
|
36
|
+
},
|
|
37
|
+
"require": {
|
|
38
|
+
"types": "./dist/cjs/index.d.ts",
|
|
39
|
+
"default": "./dist/cjs/index.cjs"
|
|
40
|
+
}
|
|
33
41
|
}
|
|
34
42
|
},
|
|
35
|
-
"types": "dist/js/index.d.ts",
|
|
36
43
|
"sideEffects": false,
|
|
37
44
|
"files": [
|
|
38
45
|
"dist"
|
|
39
46
|
],
|
|
40
47
|
"scripts": {
|
|
41
|
-
"bench": "
|
|
42
|
-
"build": "
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"test": "npm-run-all test:*",
|
|
47
|
-
"test:tape": "ts-node -r esm test.js"
|
|
48
|
+
"bench": "tsx bench.ts",
|
|
49
|
+
"build": "tsup --config ../../tsup.config.ts",
|
|
50
|
+
"docs": "tsx ../../scripts/generate-readmes.ts",
|
|
51
|
+
"test": "npm-run-all --npm-path npm test:*",
|
|
52
|
+
"test:tape": "tsx test.ts"
|
|
48
53
|
},
|
|
49
54
|
"devDependencies": {
|
|
50
|
-
"@types/
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
55
|
+
"@types/benchmark": "^2.1.5",
|
|
56
|
+
"@types/tape": "^4.2.32",
|
|
57
|
+
"benchmark": "^2.1.4",
|
|
58
|
+
"load-json-file": "^7.0.1",
|
|
59
|
+
"npm-run-all": "^4.1.5",
|
|
60
|
+
"tape": "^5.7.2",
|
|
61
|
+
"tsup": "^8.0.1",
|
|
62
|
+
"tsx": "^4.6.2",
|
|
63
|
+
"typescript": "^5.2.2",
|
|
64
|
+
"write-json-file": "^5.0.0"
|
|
59
65
|
},
|
|
60
66
|
"dependencies": {
|
|
61
|
-
"@turf/distance-weight": "^7.0.0-alpha.
|
|
62
|
-
"@turf/helpers": "^7.0.0-alpha.
|
|
63
|
-
"@turf/meta": "^7.0.0-alpha.
|
|
64
|
-
"tslib": "^2.
|
|
67
|
+
"@turf/distance-weight": "^7.0.0-alpha.110+1411d63a7",
|
|
68
|
+
"@turf/helpers": "^7.0.0-alpha.110+1411d63a7",
|
|
69
|
+
"@turf/meta": "^7.0.0-alpha.110+1411d63a7",
|
|
70
|
+
"tslib": "^2.6.2"
|
|
65
71
|
},
|
|
66
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "1411d63a74c275c9216fe48e9d3cb2d48a359068"
|
|
67
73
|
}
|
package/dist/es/index.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import spatialWeight from "@turf/distance-weight";
|
|
2
|
-
import { featureEach } from "@turf/meta";
|
|
3
|
-
/**
|
|
4
|
-
* Moran's I measures patterns of attribute values associated with features.
|
|
5
|
-
* The method reveal whether similar values tend to occur near each other,
|
|
6
|
-
* or whether high or low values are interspersed.
|
|
7
|
-
*
|
|
8
|
-
* Moran's I > 0 means a clusterd pattern.
|
|
9
|
-
* Moran's I < 0 means a dispersed pattern.
|
|
10
|
-
* Moran's I = 0 means a random pattern.
|
|
11
|
-
*
|
|
12
|
-
* In order to test the significance of the result. The z score is calculated.
|
|
13
|
-
* A positive enough z-score (ex. >1.96) indicates clustering,
|
|
14
|
-
* while a negative enough z-score (ex. <-1.96) indicates a dispersed pattern.
|
|
15
|
-
*
|
|
16
|
-
* the z-score can be calculated based on a normal or random assumption.
|
|
17
|
-
*
|
|
18
|
-
* **Bibliography***
|
|
19
|
-
*
|
|
20
|
-
* 1. [Moran's I](https://en.wikipedia.org/wiki/Moran%27s_I)
|
|
21
|
-
*
|
|
22
|
-
* 2. [pysal](http://pysal.readthedocs.io/en/latest/index.html)
|
|
23
|
-
*
|
|
24
|
-
* 3. Andy Mitchell, The ESRI Guide to GIS Analysis Volume 2: Spatial Measurements & Statistics.
|
|
25
|
-
*
|
|
26
|
-
* @name moranIndex
|
|
27
|
-
* @param {FeatureCollection<any>} fc
|
|
28
|
-
* @param {Object} options
|
|
29
|
-
* @param {string} options.inputField the property name, must contain numeric values
|
|
30
|
-
* @param {number} [options.threshold=100000] the distance threshold
|
|
31
|
-
* @param {number} [options.p=2] the Minkowski p-norm distance parameter
|
|
32
|
-
* @param {boolean} [options.binary=false] whether transfrom the distance to binary
|
|
33
|
-
* @param {number} [options.alpha=-1] the distance decay parameter
|
|
34
|
-
* @param {boolean} [options.standardization=true] wheter row standardization the distance
|
|
35
|
-
* @returns {MoranIndex}
|
|
36
|
-
* @example
|
|
37
|
-
*
|
|
38
|
-
* const bbox = [-65, 40, -63, 42];
|
|
39
|
-
* const dataset = turf.randomPoint(100, { bbox: bbox });
|
|
40
|
-
*
|
|
41
|
-
* const result = turf.moranIndex(dataset, {
|
|
42
|
-
* inputField: 'CRIME',
|
|
43
|
-
* });
|
|
44
|
-
*/
|
|
45
|
-
export default function (fc, options) {
|
|
46
|
-
const inputField = options.inputField;
|
|
47
|
-
const threshold = options.threshold || 100000;
|
|
48
|
-
const p = options.p || 2;
|
|
49
|
-
const binary = options.binary || false;
|
|
50
|
-
const alpha = options.alpha || -1;
|
|
51
|
-
const standardization = options.standardization || true;
|
|
52
|
-
const weight = spatialWeight(fc, {
|
|
53
|
-
alpha,
|
|
54
|
-
binary,
|
|
55
|
-
p,
|
|
56
|
-
standardization,
|
|
57
|
-
threshold,
|
|
58
|
-
});
|
|
59
|
-
const y = [];
|
|
60
|
-
featureEach(fc, (feature) => {
|
|
61
|
-
const feaProperties = feature.properties || {};
|
|
62
|
-
// validate inputField exists
|
|
63
|
-
y.push(feaProperties[inputField]);
|
|
64
|
-
});
|
|
65
|
-
const yMean = mean(y);
|
|
66
|
-
const yVar = variance(y);
|
|
67
|
-
let weightSum = 0;
|
|
68
|
-
let s0 = 0;
|
|
69
|
-
let s1 = 0;
|
|
70
|
-
let s2 = 0;
|
|
71
|
-
const n = weight.length;
|
|
72
|
-
// validate y.length is the same as weight.length
|
|
73
|
-
for (let i = 0; i < n; i++) {
|
|
74
|
-
let subS2 = 0;
|
|
75
|
-
for (let j = 0; j < n; j++) {
|
|
76
|
-
weightSum += weight[i][j] * (y[i] - yMean) * (y[j] - yMean);
|
|
77
|
-
s0 += weight[i][j];
|
|
78
|
-
s1 += Math.pow(weight[i][j] + weight[j][i], 2);
|
|
79
|
-
subS2 += weight[i][j] + weight[j][i];
|
|
80
|
-
}
|
|
81
|
-
s2 += Math.pow(subS2, 2);
|
|
82
|
-
}
|
|
83
|
-
s1 = 0.5 * s1;
|
|
84
|
-
const moranIndex = weightSum / s0 / yVar;
|
|
85
|
-
const expectedMoranIndex = -1 / (n - 1);
|
|
86
|
-
const vNum = n * n * s1 - n * s2 + 3 * (s0 * s0);
|
|
87
|
-
const vDen = (n - 1) * (n + 1) * (s0 * s0);
|
|
88
|
-
const vNorm = vNum / vDen - expectedMoranIndex * expectedMoranIndex;
|
|
89
|
-
const stdNorm = Math.sqrt(vNorm);
|
|
90
|
-
const zNorm = (moranIndex - expectedMoranIndex) / stdNorm;
|
|
91
|
-
return {
|
|
92
|
-
expectedMoranIndex,
|
|
93
|
-
moranIndex,
|
|
94
|
-
stdNorm,
|
|
95
|
-
zNorm,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* get mean of a list
|
|
100
|
-
* @param {number[]} y
|
|
101
|
-
* @returns {number}
|
|
102
|
-
*
|
|
103
|
-
*/
|
|
104
|
-
function mean(y) {
|
|
105
|
-
let sum = 0;
|
|
106
|
-
for (const item of y) {
|
|
107
|
-
sum += item;
|
|
108
|
-
}
|
|
109
|
-
return sum / y.length;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* get variance of a list
|
|
113
|
-
* @param {number[]} y
|
|
114
|
-
* @returns {number}
|
|
115
|
-
*
|
|
116
|
-
*/
|
|
117
|
-
function variance(y) {
|
|
118
|
-
const yMean = mean(y);
|
|
119
|
-
let sum = 0;
|
|
120
|
-
for (const item of y) {
|
|
121
|
-
sum += Math.pow(item - yMean, 2);
|
|
122
|
-
}
|
|
123
|
-
return sum / y.length;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* @typedef {Object} MoranIndex
|
|
127
|
-
* @property {number} moranIndex the moran's Index of the observed feature set
|
|
128
|
-
* @property {number} expectedMoranIndex the moran's Index of the random distribution
|
|
129
|
-
* @property {number} stdNorm the standard devitaion of the random distribution
|
|
130
|
-
* @property {number} zNorm the z-score of the observe samples with regard to the random distribution
|
|
131
|
-
*/
|
package/dist/es/package.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"type":"module"}
|
package/dist/js/index.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const distance_weight_1 = tslib_1.__importDefault(require("@turf/distance-weight"));
|
|
5
|
-
const meta_1 = require("@turf/meta");
|
|
6
|
-
/**
|
|
7
|
-
* Moran's I measures patterns of attribute values associated with features.
|
|
8
|
-
* The method reveal whether similar values tend to occur near each other,
|
|
9
|
-
* or whether high or low values are interspersed.
|
|
10
|
-
*
|
|
11
|
-
* Moran's I > 0 means a clusterd pattern.
|
|
12
|
-
* Moran's I < 0 means a dispersed pattern.
|
|
13
|
-
* Moran's I = 0 means a random pattern.
|
|
14
|
-
*
|
|
15
|
-
* In order to test the significance of the result. The z score is calculated.
|
|
16
|
-
* A positive enough z-score (ex. >1.96) indicates clustering,
|
|
17
|
-
* while a negative enough z-score (ex. <-1.96) indicates a dispersed pattern.
|
|
18
|
-
*
|
|
19
|
-
* the z-score can be calculated based on a normal or random assumption.
|
|
20
|
-
*
|
|
21
|
-
* **Bibliography***
|
|
22
|
-
*
|
|
23
|
-
* 1. [Moran's I](https://en.wikipedia.org/wiki/Moran%27s_I)
|
|
24
|
-
*
|
|
25
|
-
* 2. [pysal](http://pysal.readthedocs.io/en/latest/index.html)
|
|
26
|
-
*
|
|
27
|
-
* 3. Andy Mitchell, The ESRI Guide to GIS Analysis Volume 2: Spatial Measurements & Statistics.
|
|
28
|
-
*
|
|
29
|
-
* @name moranIndex
|
|
30
|
-
* @param {FeatureCollection<any>} fc
|
|
31
|
-
* @param {Object} options
|
|
32
|
-
* @param {string} options.inputField the property name, must contain numeric values
|
|
33
|
-
* @param {number} [options.threshold=100000] the distance threshold
|
|
34
|
-
* @param {number} [options.p=2] the Minkowski p-norm distance parameter
|
|
35
|
-
* @param {boolean} [options.binary=false] whether transfrom the distance to binary
|
|
36
|
-
* @param {number} [options.alpha=-1] the distance decay parameter
|
|
37
|
-
* @param {boolean} [options.standardization=true] wheter row standardization the distance
|
|
38
|
-
* @returns {MoranIndex}
|
|
39
|
-
* @example
|
|
40
|
-
*
|
|
41
|
-
* const bbox = [-65, 40, -63, 42];
|
|
42
|
-
* const dataset = turf.randomPoint(100, { bbox: bbox });
|
|
43
|
-
*
|
|
44
|
-
* const result = turf.moranIndex(dataset, {
|
|
45
|
-
* inputField: 'CRIME',
|
|
46
|
-
* });
|
|
47
|
-
*/
|
|
48
|
-
function default_1(fc, options) {
|
|
49
|
-
const inputField = options.inputField;
|
|
50
|
-
const threshold = options.threshold || 100000;
|
|
51
|
-
const p = options.p || 2;
|
|
52
|
-
const binary = options.binary || false;
|
|
53
|
-
const alpha = options.alpha || -1;
|
|
54
|
-
const standardization = options.standardization || true;
|
|
55
|
-
const weight = distance_weight_1.default(fc, {
|
|
56
|
-
alpha,
|
|
57
|
-
binary,
|
|
58
|
-
p,
|
|
59
|
-
standardization,
|
|
60
|
-
threshold,
|
|
61
|
-
});
|
|
62
|
-
const y = [];
|
|
63
|
-
meta_1.featureEach(fc, (feature) => {
|
|
64
|
-
const feaProperties = feature.properties || {};
|
|
65
|
-
// validate inputField exists
|
|
66
|
-
y.push(feaProperties[inputField]);
|
|
67
|
-
});
|
|
68
|
-
const yMean = mean(y);
|
|
69
|
-
const yVar = variance(y);
|
|
70
|
-
let weightSum = 0;
|
|
71
|
-
let s0 = 0;
|
|
72
|
-
let s1 = 0;
|
|
73
|
-
let s2 = 0;
|
|
74
|
-
const n = weight.length;
|
|
75
|
-
// validate y.length is the same as weight.length
|
|
76
|
-
for (let i = 0; i < n; i++) {
|
|
77
|
-
let subS2 = 0;
|
|
78
|
-
for (let j = 0; j < n; j++) {
|
|
79
|
-
weightSum += weight[i][j] * (y[i] - yMean) * (y[j] - yMean);
|
|
80
|
-
s0 += weight[i][j];
|
|
81
|
-
s1 += Math.pow(weight[i][j] + weight[j][i], 2);
|
|
82
|
-
subS2 += weight[i][j] + weight[j][i];
|
|
83
|
-
}
|
|
84
|
-
s2 += Math.pow(subS2, 2);
|
|
85
|
-
}
|
|
86
|
-
s1 = 0.5 * s1;
|
|
87
|
-
const moranIndex = weightSum / s0 / yVar;
|
|
88
|
-
const expectedMoranIndex = -1 / (n - 1);
|
|
89
|
-
const vNum = n * n * s1 - n * s2 + 3 * (s0 * s0);
|
|
90
|
-
const vDen = (n - 1) * (n + 1) * (s0 * s0);
|
|
91
|
-
const vNorm = vNum / vDen - expectedMoranIndex * expectedMoranIndex;
|
|
92
|
-
const stdNorm = Math.sqrt(vNorm);
|
|
93
|
-
const zNorm = (moranIndex - expectedMoranIndex) / stdNorm;
|
|
94
|
-
return {
|
|
95
|
-
expectedMoranIndex,
|
|
96
|
-
moranIndex,
|
|
97
|
-
stdNorm,
|
|
98
|
-
zNorm,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
exports.default = default_1;
|
|
102
|
-
/**
|
|
103
|
-
* get mean of a list
|
|
104
|
-
* @param {number[]} y
|
|
105
|
-
* @returns {number}
|
|
106
|
-
*
|
|
107
|
-
*/
|
|
108
|
-
function mean(y) {
|
|
109
|
-
let sum = 0;
|
|
110
|
-
for (const item of y) {
|
|
111
|
-
sum += item;
|
|
112
|
-
}
|
|
113
|
-
return sum / y.length;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* get variance of a list
|
|
117
|
-
* @param {number[]} y
|
|
118
|
-
* @returns {number}
|
|
119
|
-
*
|
|
120
|
-
*/
|
|
121
|
-
function variance(y) {
|
|
122
|
-
const yMean = mean(y);
|
|
123
|
-
let sum = 0;
|
|
124
|
-
for (const item of y) {
|
|
125
|
-
sum += Math.pow(item - yMean, 2);
|
|
126
|
-
}
|
|
127
|
-
return sum / y.length;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* @typedef {Object} MoranIndex
|
|
131
|
-
* @property {number} moranIndex the moran's Index of the observed feature set
|
|
132
|
-
* @property {number} expectedMoranIndex the moran's Index of the random distribution
|
|
133
|
-
* @property {number} stdNorm the standard devitaion of the random distribution
|
|
134
|
-
* @property {number} zNorm the z-score of the observe samples with regard to the random distribution
|
|
135
|
-
*/
|