We provide two data generative process for generating network dependent outcomes–network dependence due to (1) direct transmission and (2) latent variable dependence.
Under direct transmission, peer.process
provides time-evolving outcomes where \(Y^{t}_{i}\) depends on \(\{ Y^{t}_{j} : j \mbox{ is an adjacent peers of } i \}\).
library(knitr)
library(netdep)
library(MASS)
library(mvrtn)
library(igraph)
library(igraphdata)
# generate network
G = latent.netdep(n.node = 200, rho = 0.2, dep.factor = -1)
A = as.matrix(get.adjacency(G))
outcomes = peer.process(A, max.time = 3, mprob = 0.6, epsilon = 0.1)
names(outcomes)
#> [1] "time0" "time1" "time2" "time3"
result0 = make.permute.moran(A, outcomes$time0, np = 100)
result1 = make.permute.moran(A, outcomes$time1, np = 100)
result2 = make.permute.moran(A, outcomes$time2, np = 100)
result3 = make.permute.moran(A, outcomes$time3, np = 100)
kable(cbind( c("t=0", "t=1", "t=2", "t=3"),
round(c(result0$moran, result1$moran, result2$moran, result3$moran),2),
round(c(result0$pval.permute, result1$pval.permute, result2$pval.permute, result3$pval.permute),2)), row.names = NA, col.names = c("Transmission time", "Moran's I", "P-value (permutation)"),
caption = "Direct transmission")
Transmission time | Moran’s I | P-value (permutation) |
---|---|---|
t=0 | 0.6 | 0.23 |
t=1 | 1.63 | 0.06 |
t=2 | 2.68 | 0.01 |
t=3 | 3.45 | 0.01 |
Note from the above table that as t
increases, Moran’s \(I\) statistic increases and p-value decreases.
Next we generate network dependent continuous outcomes via (2) latent variable dependence, and then transform those into categorical outcomes, where \(\Phi\) statistic can be applicable to test network dependence.
G = latent.netdep(n.node = 200, rho = 0.4, dep.factor = -1)
subG = snowball.sampling(G, 100)$subG
A = as.matrix(get.adjacency(subG))
conti.Y = V(subG)$outcome
cate.Y = ifelse(conti.Y < quantile(conti.Y, 0.25), 1, 4)
cate.Y = ifelse(conti.Y < quantile(conti.Y, 0.60) & conti.Y >= quantile(conti.Y, 0.25), 2, cate.Y)
cate.Y = ifelse(conti.Y < quantile(conti.Y, 0.80) & conti.Y >= quantile(conti.Y, 0.60), 3, cate.Y)
table(cate.Y)
#> cate.Y
#> 1 2 3 4
#> 25 35 20 20
result = make.permute.Phi(A, cate.Y, 100)
print(result$phi)
#> [1] 2.020674
print(result$pval.permute)
#> [1] 0.04
We first apply two test statistics in binary case – faction of karate club.
library(igraphdata)
data(karate)
A = as.matrix(as_adjacency_matrix(karate, attr= "weight", sparse = T)) # weighted adjacency matrix
Y = V(karate)$Faction
table(Y) # binary
#> Y
#> 1 2
#> 16 18
result.moran = make.permute.moran(A, Y, np = 100)
print(result.moran$moran)
#> [,1]
#> [1,] 7.977004
print(result.moran$pval.permute)
#> [,1]
#> [1,] 0.01
result.phi = make.permute.Phi(A, Y, np = 100)
print(result.phi$phi)
#> [1] 7.977004
print(result.phi$pval.permute)
#> [1] 0.01
Observe that Moran’s \(I\) and \(\Phi\) print out the same statistis.
When outcome is categorical (nominal) but not binary, we can use \(\Phi\).
data(UKfaculty)
A = as.matrix(as_adjacency_matrix(UKfaculty, attr= "weight", sparse = T)) # weighted adjacency matrix
Y = V(UKfaculty)$Group
table(Y)
#> Y
#> 1 2 3 4
#> 33 27 19 2
result = make.permute.Phi(A, Y, np = 50)
print(result$phi)
#> [1] 6.168282
print(result$pval.permute)
#> [1] 0.02
More details on the method and applications can be found in Arxiv paper.