This vignette documents the implementation of NBR 0.1.3 for linear models.
We will analyze the frontal3D
dataset, which contains a 3D volume of 48 matrices, each matrix representing the functional connectivity between 28 nodes (in the frontal lobe). Phenotypic information (frontal_phen
) includes diagnostic GROUP (patient or control), sex, and age. We will test for a GROUP effect.
library(NBR)
<- NBR:::frontal3D # Load 3D array
cmx <- NBR:::frontal_roi # Load node labels
brain_labs <- NBR:::frontal_phen # Load phenotypic info
phen dim(cmx) # Show 3D array dimensions
#> [1] 28 28 48
We can plot the sample average matrix, with lattice::levelplot
.
library(lattice)
<- apply(cmx, 1:2, mean)
avg_mx # Set max-absolute value in order to set a color range centered in zero.
<- max(abs(avg_mx)[is.finite(avg_mx)])
flim levelplot(avg_mx, main = "Average", ylab = "ROI", xlab = "ROI",
at = seq(-flim, flim, length.out = 100))
As we can observe, this is a symmetric matrix with the pairwise connections of the 28 regions of interest (ROI) brain_labs
. The next step is to check the phenotypic information (stored in phen
) to perform statistic inferences edgewise. Before applying the NBR-LM, we check that the number of matrices (3rd dimension in the dataset) matches the number of observations in the phen
data.frame.
head(phen)
#> Group Sex Age
#> 1 Control F 8.52
#> 2 Control M 16.16
#> 3 Patient M 17.75
#> 4 Control M 12.27
#> 5 Control F 12.07
#> 6 Patient F 8.71
nrow(phen)
#> [1] 48
identical(nrow(phen), dim(cmx)[3])
#> [1] TRUE
The data.frame contains the individual information for diagnostic group, sex, and chronological age. So, we are all set to perform an NBR-LM. We are going to test the effect of diagnostic group with a minimal number of permutations to check that we have no errors.
set.seed(18900217) # Because R. Fisher is my hero
<- Sys.time()
before <- nbr_lm_aov(net = cmx, nnodes = 28, idata = phen,
nbr_group mod = "~ Group", thrP = 0.01, nperm = 10)
#> Computing observed stats.
#> Computing permutated stats.
#> Permutation progress: ....
<- Sys.time()
after show(after-before)
#> Time difference of 12.33499 secs
Although ten permutations is quite low to obtain a proper null distribution, we can see that they take several seconds to be performed. So we suggest to paralleling to multiple CPU cores with cores
argument.
set.seed(18900217)
library(parallel)
<- Sys.time()
before <- nbr_lm_aov(net = cmx, nnodes = 28, idata = phen,
nbr_group mod = "~ Group", thrP = 0.01, nperm = 100, cores = detectCores())
<- Sys.time()
after length(nbr_group)
NBR functions return a nested list of at least two lists. The first list encompasses all the individual significant edges, their corresponding component and statistical inference (p < 0.01, in this example). In this case all the significant edges belong to a single component.
# Plot significant component
<- array(0, dim(avg_mx))
edge_mat $components$Group[,2:3]] <- 1
edge_mat[nbr_grouplevelplot(edge_mat, col.regions = rev(heat.colors(100)),
main = "Component", ylab = "ROI", xlab = "ROI")
show(nbr_group$fwe$Group)
#> Component ncomp ncompFWE strn strnFWE
#> 1 1 28 0 64.52926 0
As we can observe, significant edges are displayed in the upper triangle of the matrix, and the second list (fwe
) contains, for each term of the equation, the probability of the observed values to occur by chance, based on the null distribution.