diff --git a/esda/moran.py b/esda/moran.py index 5bc85316..15f97a9e 100644 --- a/esda/moran.py +++ b/esda/moran.py @@ -889,6 +889,10 @@ class Moran_Local(object): value to use as a weight for the "fake" neighbor for every island. If numpy.nan, will propagate to the final local statistic depending on the `stat_func`. If 0, then the lag is always zero for islands. + alternative: {"two-tailed", "one-tailed"} + default="two-tailed") + "two-tailed" test for the possibility of the relationship in both directions + "one-tailed" to detect an effect in one direction by not testing the effect in the other direction Attributes ---------- @@ -1005,6 +1009,7 @@ def __init__( keep_simulations=True, seed=None, island_weight=0, + alternative = "two-tailed" ): y = np.asarray(y).flatten() self.y = y @@ -1063,6 +1068,12 @@ def __init__( self.VI_sim = np.nan self.z_sim = np.nan self.p_z_sim = np.nan + if alternative=="one-tailed": + self.p_z_sim= self.p_z_sim*2 + folded_replicates = np.abs(self.rlisas - np.median(self.rlisas, axis=1, keepdims=True)) + self.p_sim = (folded_replicates >= np.abs(self.Is[:,None])).mean(axis=1) + + def __calc(self, w, z): zl = slag(w, z) @@ -1575,6 +1586,7 @@ def __init__( keep_simulations=True, seed=None, island_weight=0, + alternative="two-tailed" ): e = np.asarray(e).flatten() b = np.asarray(b).flatten() @@ -1592,6 +1604,7 @@ def __init__( n_jobs=n_jobs, keep_simulations=keep_simulations, seed=seed, + alternative=alternative ) @classmethod diff --git a/esda/tests/test_moran.py b/esda/tests/test_moran.py index 65319885..125877a1 100644 --- a/esda/tests/test_moran.py +++ b/esda/tests/test_moran.py @@ -118,6 +118,19 @@ def test_Moran_Local(self): self.assertAlmostEqual(lm.z_sim[0], -0.6990291160835514) self.assertAlmostEqual(lm.p_z_sim[0], 0.24226691753791396) + def test_Moran_Local_two_tailed(self): + lm = moran.Moran_Local( + self.y, + self.w, + transformation="r", + permutations=99, + keep_simulations=True, + seed=SEED, + alternative="two-tailed" + ) + self.assertAlmostEqual(lm.z_sim[0], -0.6990291160835514) + self.assertAlmostEqual(lm.p_z_sim[0], 0.24226691753791396) + def test_Moran_Local_parallel(self): lm = moran.Moran_Local( self.y, @@ -131,6 +144,47 @@ def test_Moran_Local_parallel(self): self.assertAlmostEqual(lm.z_sim[0], -0.6990291160835514) self.assertAlmostEqual(lm.p_z_sim[0], 0.24226691753791396) + def test_Moran_Local_two_tailed_parallel(self): + lm = moran.Moran_Local( + self.y, + self.w, + transformation="r", + n_jobs=-1, + permutations=99, + keep_simulations=True, + seed=SEED, + alternative="two-tailed" + ) + self.assertAlmostEqual(lm.z_sim[0], -0.6990291160835514) + self.assertAlmostEqual(lm.p_z_sim[0], 0.24226691753791396) + + def test_Moran_Local_one_tailed(self): + lm = moran.Moran_Local( + self.y, + self.w, + transformation="r", + permutations=99, + keep_simulations=True, + seed=SEED, + alternative="one-tailed", + ) + self.assertAlmostEqual(lm.z_sim[0], -0.6990291160835514) + self.assertAlmostEqual(lm.p_z_sim[0], 0.4845338350758279) + + def test_Moran_Local_one_tailed_parallel(self): + lm = moran.Moran_Local( + self.y, + self.w, + transformation="r", + n_jobs=-1, + permutations=99, + keep_simulations=True, + seed=SEED, + alternative="one-tailed" + ) + self.assertAlmostEqual(lm.z_sim[0], -0.6990291160835514) + self.assertAlmostEqual(lm.p_z_sim[0], 0.4845338350758279) + @unittest.skip("This function is being deprecated in the next release.") def test_by_col(self):