These analyses take all subjects from the Discovery and Replication samples who have Episodic Memory data from the CamCAN behavioral task to investigate the relationship between PMN connectivity patterns during movie watching and episodic memory.
This script uses intersubject representational similarity (IS-RSA) of brain and behavior, see Finn et al., 2020.
Intersubject brain and behavior representational dissimilarity matrices (RDMs) are first generated – the brain matrix reflects the dissimilarity of PMN time-varying connectivity (or activity, control analysis) between every pair of subjects using 1-pearson’s correlation. The behavior matrix reflects the dissimilarity between two subjects’ detailed episodic memory scores, calculated using both Nearest Neighbor (NN) and ‘Anna K’ models:
Then, the spearman correlation is computed between the lower triangle of the behavior and brain intersubject RDMs. Permutation tests, shuffling subject labels in the brain matrix, are used to test the signficance of the intersubject brain-behavior relationship.
library(gridExtra)
library(grid)
library(cowplot)
library(ggpubr)
library(tidyverse)
library(knitr)
library(psych)
library(reshape2)
library(pander)
library(lessR)
library(rstatix)
library(abind)
### load in all functions:
se <- function(x) sqrt(var(x)/length(x)) #function to calculate SE
ci <- function(x) (sqrt(var(x)/length(x))) * 1.96 #function to calculate 95% CI
## colors of PMN subsystems
module.colors <- c("#fcd841","#3c7ff5","#8ce9f7") #for "Dorsal", "Ventral", "Ventral-Dorsal"
heat.colors <- colorRampPalette(c("#009FFF","white","#ff5858"))
nIter = 10000 #number of permutations: 10,000 for publication
cat('Intersubject RSA p values computed over',nIter,'permutations')
## Intersubject RSA p values computed over 10000 permutations
R package information
sessionInfo()
## R version 3.5.1 (2018-07-02)
## Platform: x86_64-apple-darwin15.6.0 (64-bit)
## Running under: macOS High Sierra 10.13.6
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## attached base packages:
## [1] grid stats graphics grDevices utils datasets methods
## [8] base
##
## other attached packages:
## [1] abind_1.4-5 rstatix_0.6.0 lessR_3.8.1 pander_0.6.3
## [5] reshape2_1.4.3 psych_1.8.10 knitr_1.20 forcats_0.4.0
## [9] stringr_1.4.0 dplyr_0.8.5 purrr_0.3.2 readr_1.1.1
## [13] tidyr_1.0.2 tibble_3.0.2 tidyverse_1.2.1 ggpubr_0.1.8
## [17] magrittr_1.5 cowplot_0.9.3 ggplot2_3.1.0 gridExtra_2.3
##
## loaded via a namespace (and not attached):
## [1] httr_1.3.1 jsonlite_1.5 viridisLite_0.3.0
## [4] carData_3.0-2 ellipse_0.4.1 modelr_0.1.2
## [7] assertthat_0.2.1 latticeExtra_0.6-28 cellranger_1.1.0
## [10] yaml_2.2.0 robustbase_0.93-3 pillar_1.4.4
## [13] backports_1.1.2 lattice_0.20-35 glue_1.3.2
## [16] digest_0.6.18 RColorBrewer_1.1-2 rvest_0.3.2
## [19] colorspace_1.4-1 htmltools_0.3.6 plyr_1.8.4
## [22] pkgconfig_2.0.2 sas7bdat_0.5 broom_0.7.0
## [25] triangle_0.11 wesanderson_0.3.6 haven_1.1.2
## [28] scales_1.0.0 openxlsx_4.1.0 Rtsne_0.15
## [31] rio_0.5.10 car_3.0-2 generics_0.0.2
## [34] ellipsis_0.3.0 withr_2.1.2 randomcoloR_1.1.0
## [37] lazyeval_0.2.2 cli_1.1.0 mnormt_1.5-5
## [40] crayon_1.3.4 readxl_1.1.0 evaluate_0.12
## [43] nlme_3.1-137 xml2_1.2.0 foreign_0.8-71
## [46] data.table_1.11.8 tools_3.5.1 hms_0.4.2
## [49] lifecycle_0.2.0 V8_1.5 munsell_0.5.0
## [52] cluster_2.0.7-1 zip_1.0.0 compiler_3.5.1
## [55] rlang_0.4.5 rstudioapi_0.8 leaps_3.0
## [58] rmarkdown_1.10 gtable_0.3.0 curl_4.3
## [61] R6_2.4.0 lubridate_1.7.4 rprojroot_1.3-2
## [64] stringi_1.4.3 parallel_3.5.1 Rcpp_1.0.1
## [67] vctrs_0.2.4 png_0.1-7 DEoptimR_1.0-8
## [70] tidyselect_1.0.0
Episodic memory scores reflect detailed source memory – the number of trials where subjects verbally reported specific details about the scene context of an object.
Note that this task contains an emotion manipulation (scene contexts can be negative, neutral, or positive valence), so only neutral trials are considered here. Although detailed memory scores for the neutral-only condition correlate extremely highly with scores across all conditions.
# all fmri subjects who also have behavioral data from independent task:
behav.data <- read.csv('../../behavioral-data/EmotionalMemory_subset.csv')
# remove one subject with a VERY high number of error trials:
subs_remove <- c('sub-CC220203')
#grab relevant measures
behav.data <- behav.data[-c(match(subs_remove,behav.data$SubID)),c("SubID","PriPrNeu","DetNeuPic")]
# PriPrNeu = corrected priming score of neutral condition objects (for a control analysis)
# DetNeuPic = number of trials for which participants had detailed memory for the object's (neutral) scene context
colnames(behav.data) <- c("SubID","Priming","Episodic")
# order subjects (I'll do the same ordering when loading fmri data)
behav.data <- behav.data[order(as.character(behav.data$SubID)),]
behav.data$SubID=factor(behav.data$SubID, levels=as.character(behav.data$SubID))
NSubs=nrow(behav.data)
cat(NSubs,'subjects who have episodic memory data available for analysis')
## 67 subjects who have episodic memory data available for analysis
#order of subjects by behavioral score, for visualizing matrices
episodic.ord <- order(behav.data$Episodic, decreasing = F)
priming.ord <- order(behav.data$Priming, decreasing = F)
Correlation between episodic and priming (control measure) scores and distribution of episodic data:
my.cor <- cor.test(behav.data$Priming, behav.data$Episodic)
# plot IQ ~ Memory across subject
p1 <- ggplot(behav.data, aes(x=Episodic, y=Priming)) +
geom_point(aes(color=Episodic),size=5) +
geom_smooth(method = "lm", color="black", size=2) +
geom_label(label=paste('r=',round(my.cor$estimate,3),sep=""), x=32, y=0, size=8) +
ggtitle('Priming and\nDetailed Episodic Memory') +
theme(plot.title = element_text(hjust = 0.5, size=32, face="plain"),
axis.line.x = element_line(color = "black", size = 1), axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 20), axis.text.y = element_text(size = 24),
axis.title.y = element_text(size = 28, margin=margin(0,10,0,0)),
axis.title.x = element_text(size = 28, margin=margin(10,0,0,0)),
panel.background = element_blank(),
legend.position="none", strip.text.x = element_text(size=22),
plot.margin = margin(1, 0.5, 0.5, 0.5, "cm"))
### now plot episodic distribution
p2 <- ggplot(behav.data, aes(x=Episodic, y=..count..)) +
geom_histogram(bins=10, color="gray60",fill="gray60") +
ggtitle('Detailed Episodic Memory Scores') +
scale_y_continuous(expand=c(.01,0,.1,0)) + ylab('N Subjects') +
theme(plot.title = element_text(hjust = 0.5, size=32, face="plain"),
axis.line.x = element_line(color = "black", size = 1), axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 20), axis.text.y = element_text(size = 24),
axis.title.y = element_text(size = 28, margin=margin(0,10,0,0)),
axis.title.x = element_text(size = 28, margin=margin(10,0,0,0)),
panel.background = element_blank(),
legend.position="none", strip.text.x = element_text(size=22),
plot.margin = margin(1, 0.5, 0.5, 0.5, "cm"))
ggarrange(p1,p2,ncol=2,nrow=1,widths=c(2,3))
Time-averaged module connectivity as calculated from the the correlation of time-series over the entire duration of the movie within CamCan-PM-network_[Discovery/Replication].Rmd. Does average connectvity strength relate to episodic memory performance?
# grab module connectivity from both groups
load('./Discovery/module-connectivity_Discovery.RData')
module.A <- data.summary.subject
load('./Replication/module-connectivity_Replication.RData')
module.B <- data.summary.subject
module.conn <- rbind(module.A,module.B)
modules <- unique(module.conn$Module)
#filter by subjects who have behavioral data and **match order to behavioral data**
sub.idx <- module.conn$Var3 %in% behav.data$SubID
module.conn <- module.conn[sub.idx,]
module.conn <- module.conn[order(as.character(module.conn$Var3)),]
module.conn$Var3=factor(module.conn$Var3, levels=as.character(behav.data$SubID))
colnames(module.conn)[1] <- "SubID"
### correlation between module connectivity and EPISODIC
plots <- list()
cor.data <- data.frame(Module = modules, r = array(0,length(modules)), p = array(0,length(modules)))
for (m in 1:length(modules)) {
# connectivity values for this module
mod.subset <- subset(module.conn, Module == modules[m])
# merge connectivity values and behavior values by subject ID
mod.data <- merge(mod.subset, behav.data, by="SubID")
c = cor.test(mod.data$Strength, mod.data$Episodic)
cor.data[m,] <- c(modules[m], round(c$estimate,3), round(c$p.value,3))
# plot
min.x <- min(mod.data$Strength + .1) # for correlation label
plots[[m]] <- ggplot(mod.data, aes(x=Strength, y=Episodic)) +
geom_point(color=module.colors[m], size=4) +
ggtitle(modules[m]) +
geom_smooth(method = "lm", color="black", size=2) +
geom_label(x=min.x, y=39, size=5,
label = paste('r =',round(c$estimate,3),sep=" ")) +
scale_y_continuous(limits=c(0,40)) +
labs(y="Episodic Memory", x="Connectivity Strength") +
theme(plot.title = element_text(hjust = 0.5, size=28, face="plain"),
axis.line.x = element_line(color = "black", size = 1), axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 18), axis.text.y = element_text(size = 18),
axis.title.y = element_text(size = 20, margin=margin(0,10,0,0)),
axis.title.x = element_text(size = 20, margin=margin(10,0,0,0)),
panel.background = element_blank(),
legend.position="none", strip.text.x = element_text(size=22),
plot.margin = margin(0.5, 0.5, 0.5, 0.5, "cm"))
}
kable(cor.data, caption="Correlation between module connectivity strength and episodic memory")
Module | r | p |
---|---|---|
Dorsal | -0.079 | 0.523 |
Ventral | 0.178 | 0.151 |
Ventral-Dorsal | 0.018 | 0.883 |
meancor.plots <- ggarrange(plotlist = plots, ncol=3) +
theme(plot.tag = element_text(size = 38, face = "bold"),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm")) +
labs(tag="a")
Now, I am loading in the time-varying connectivity vectors generated within CamCan-PM-network_[Discovery/Replication].Rmd, which reflect the mean connectivity within the Ventral and Dorsal subsystems, and between them, per subject and time point.
# grab time series from both groups
load('./Discovery/time-varying_Discovery.RData')
module.A <- TV.module.connectivity
load('./Replication/time-varying_Replication.RData')
module.B <- TV.module.connectivity
TV <- rbind(module.A,module.B)
#filter by subjects who have behavioral data and **match order to behavioral data**
sub.idx <- TV$Subject %in% behav.data$SubID
TV <- TV[sub.idx,]
TV <- TV[order(as.character(TV$Subject)),]
TV$Subject=factor(TV$Subject, levels=as.character(behav.data$SubID))
TV$Module=as.factor(TV$Module)
Intersubject RSA for episodic memory scores:
#### initiate stats data frame for time-varying connectivity NN and Anna K models
my.stats <- data.frame(array(0,c(length(modules)*2,4)))
colnames(my.stats) <- c('Model','Module','r','p')
ord <- episodic.ord #order to sort subjects by for visualization (they are sorted in numeric order for analyses)
### calculate subjxsubj correlation matrices, by PMN subsystem
module.RDMs.Time <- array(0,c(NSubs,NSubs,length(modules)))
plots.images = list()
for (m in 1:length(modules)) {
module_data <- subset(TV, Module == modules[m]) %>% #time-varying connectivity for this subsystem
spread(Subject, Conn) %>% #now spread so subjects are in columns
droplevels()
# which columns are subjects?
subcols <- grep('sub-',colnames(module_data))
# correlate subject time series, taking **dissimilarity (1- pearson correlation)**
module_matrix <- 1 - cor(module_data[,subcols])
diag(module_matrix) <- NA
# catch to make sure subID col names are in same order as behavData subIDs
check = setdiff(as.character(behav.data$SubID),colnames(module_matrix))
if (!is_empty(check)) { stop('SubID order in brain RDM does not match behavioral data')}
## store (in behav subject order)
module.RDMs.Time[,,m] <- module_matrix
#sort by behavioral *score* for visualization purposes
module.matrix.sort <- data.frame(module_matrix[ord,ord])
colnames(module.matrix.sort) <- 1:nrow(module.matrix.sort)
module.matrix.sort$Subject <- 1:nrow(module.matrix.sort)
plots.images[[m]] <- ggplot(melt(module.matrix.sort,"Subject"),
aes(Subject, variable, fill=value)) +
geom_tile() +
scale_fill_gradientn(colors = heat.colors(10), na.value = "gray80",
guide = guide_colorbar(frame.colour = "black"),
limits=c(0,2)) +
ggtitle(modules[m]) + labs(fill="Dissimilarity", y="Subject") +
scale_x_continuous(breaks = c(12,55), labels = c("Low Memory", "High Memory")) +
scale_y_discrete(breaks = c(12,55), labels = c("Low Memory", "High Memory")) +
theme(plot.title = element_text(hjust = 0.5, size=26, margin=margin(0,0,10,0), face="plain"),
axis.text.x = element_text(hjust = 0.5, size=16), axis.ticks.x = element_blank(),
axis.line.x = element_blank(), axis.title.x = element_text(hjust = 0.5, size=18),
axis.text.y = element_text(hjust = 0.5, size=16, angle=90, vjust=-4), axis.ticks.y = element_blank(),
axis.line.y = element_blank(), axis.title.y = element_text(hjust = 0.5, size=18, vjust=-4),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"))
}
ggarrange(plotlist = plots.images, ncol = 3)
colnames(module.RDMs.Time) <- colnames(module_matrix)
rownames(module.RDMs.Time) <- rownames(module_matrix)
#out of full matrices, we'll just use the unique correlations in lower triangle for brain-behavior RDMs
unique.idx <- which(lower.tri(module.RDMs.Time[,,1], diag=F))
For this first model, the distance between subjects’ behavioral scores is simply abs(i-j). So, regardless of how well or poorly they did on the task, we’re assuming that similar subjects should have similar patterns of time-varying connectivity.
#### BEHAVIOR RDM #######
episodic.scores <- t(spread(subset(behav.data, select=-c(Priming)), SubID, Episodic))
behav.RDM.matrix.NN <- as.matrix(dist(episodic.scores, method='euclidean')) #dist takes distance between rows (subjects' scores)
diag(behav.RDM.matrix.NN) <- NA
# catch to make sure brain RDM subject order is the same as behavior RDM subject order
check = setdiff(colnames(behav.RDM.matrix.NN),colnames(module.RDMs.Time))
if (!is_empty(check)) { stop('SubID order in brain RDM does not match behavior RDM')}
# store in subject order for RDM comparison
this.behav <- behav.RDM.matrix.NN
## plot sorting by behavioral score for visualization
behav.RDM.matrix.sort <- behav.RDM.matrix.NN[ord,ord]
behav.RDM <- data.frame(behav.RDM.matrix.sort)
colnames(behav.RDM) <- 1:nrow(behav.RDM)
behav.RDM$Subject <- 1:nrow(behav.RDM)
p1 <- ggplot(melt(behav.RDM, "Subject"),
aes(Subject, variable, fill=value, color=value)) +
geom_tile() +
scale_fill_gradientn(limits=c(0,34),
colors = heat.colors(10), na.value = "gray80",
guide = guide_colorbar(frame.colour = "black")) +
scale_color_gradientn(limits=c(0,34),
colors = heat.colors(10), na.value = "gray80",
guide = guide_colorbar(frame.colour = "black")) +
ggtitle('Nearest Neighbor') +
labs(tag="c", fill="abs(i-j)", y="Subject") +
guides(color=FALSE) +
scale_x_continuous(breaks = c(14,53), labels = c("Low Memory", "High Memory")) +
scale_y_discrete(breaks = c(14,53), labels = c("Low Memory", "High Memory")) +
theme(plot.title = element_text(hjust = 0.5, size=28, margin=margin(0,0,10,0), face="plain"),
axis.text.x = element_text(hjust = 0.5, size=18), axis.ticks.x = element_blank(),
axis.line.x = element_blank(), axis.title.x = element_text(hjust = 0.5, size=22),
axis.text.y = element_text(hjust = 0.5, size=18, angle=90, vjust=-4), axis.ticks.y = element_blank(),
axis.line.y = element_blank(), axis.title.y = element_text(hjust = 0.5, size=22, vjust=-4),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"),
plot.tag = element_text(size = 38, face = "bold"),
legend.text = element_text(size=14),
legend.title = element_text(size=18, margin = margin(0,0,5,0)),
legend.key.width = unit(0.5,"cm"), legend.key.height = unit(1,"cm"))
Run intersubject RSA with permutation testing:
#### ---------- by Module ------------- #####
plots.images = list()
for (m in 1:length(modules)) {
# brain RDM for this module
this.brain <- module.RDMs.Time[,,m]
# correlate lower triangles of brain and behavior RDMs
my.cor <- cor(this.brain[unique.idx],this.behav[unique.idx], method="spearman")
# store null distribution of brain-behav correlations
perm.cors <- array(NA,c(1,nIter))
for (i in 1:nIter) {
this.order <- sample(c(1:nrow(this.brain)))
brain.shuffled <- this.brain[this.order,this.order] #shuffled subj labels on brain matrix
perm.cors[i] <- cor(brain.shuffled[unique.idx],this.behav[unique.idx], method="spearman")
}
perm.cors <- data.frame(t(perm.cors))
colnames(perm.cors) <- 'Spearman'
### plot null (permutation cors), making actual cor
plots.images[[m]] <- ggplot(perm.cors, aes(x=Spearman, y=..count..)) +
geom_histogram(binwidth = .005, fill="gray60", color="gray60") +
ggtitle(modules[m]) +
geom_vline(xintercept = my.cor, linetype=1, size=2, color=module.colors[m]) +
geom_vline(xintercept = 0, linetype=2, size=1) +
scale_y_continuous(expand=c(0,0,.02,0)) +
coord_cartesian(xlim = c(-.2,.2)) + #limits scale while ensuring no values are removed
theme(plot.title = element_text(hjust = 0.5, size=24, margin=margin(0,0,30,0), face="plain"),
axis.line.x = element_line(color = "black", size = 1),
axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 16), axis.text.y = element_text(size = 16),
axis.title.y = element_text(size = 18, margin=margin(0,10,0,0)),
axis.title.x = element_text(size = 18, margin=margin(10,0,0,0)),
panel.background = element_blank(), legend.position="none",
plot.margin = margin(0.15, 0.15, 0.15, 0.15, "cm"))
### store p values and correlations (testing if > 0)
my.stats$Model[m] <- 'NN'
my.stats$Module[m] <- modules[m]
my.stats$r[m] <- my.cor
my.stats$p[m] <- sum(perm.cors$Spearman > my.cor)/nIter
}
p2 <- ggarrange(plotlist = plots.images, ncol = 3) +
theme(plot.tag = element_text(size = 38, face = "bold"),
plot.margin = margin(0.25, 1, 0.25, 0.25, "cm")) +
labs(tag="e")
Instead of assuming similar subjects have similar brains, this model tests if subjects with good memory look similar to one another in brain patterns, but subjects with low memory performance are more variable.
Note. this model was found to fit the data best in Finn et al. (2020).
#### BEHAVIOR RDM #######
behav.RDM.matrix.AK <- array(NA,c(NSubs,NSubs))
colnames(behav.RDM.matrix.AK) <- behav.data$SubID
rownames(behav.RDM.matrix.AK) <- behav.data$SubID
# calculate Anna K dissimilarity -- i.e. max score - (min(i,j))
for (x in 1:NSubs) {
for (y in 1:NSubs) {
behav.RDM.matrix.AK[x,y] <- max(behav.data$Episodic) - (min(c(behav.data$Episodic[x],
behav.data$Episodic[y])))
}
}
diag(behav.RDM.matrix.AK) <- NA
# catch to make sure brain RDM subject order is the same as behavior RDM subject order
check = setdiff(colnames(behav.RDM.matrix.AK),colnames(module.RDMs.Time))
if (!is_empty(check)) { stop('SubID order in brain RDM does not match behavior RDM')}
# store in subject order
this.behav <- behav.RDM.matrix.AK
## plot sorting by behavioral score
behav.RDM.matrix.sort <- behav.RDM.matrix.AK[ord,ord]
behav.RDM <- data.frame(behav.RDM.matrix.sort)
colnames(behav.RDM) <- 1:nrow(behav.RDM)
behav.RDM$Subject <- 1:nrow(behav.RDM)
p3 <- ggplot(melt(behav.RDM, "Subject"),
aes(Subject, variable, fill=value, color=value)) +
geom_tile() +
scale_fill_gradientn(limits=c(0,34),
colors = heat.colors(10), na.value = "gray80",
guide = guide_colorbar(frame.colour = "black")) +
scale_color_gradientn(limits=c(0,34),
colors = heat.colors(10), na.value = "gray80",
guide = guide_colorbar(frame.colour = "black")) +
ggtitle('Anna K') +
labs(tag="d", fill="max-\nmin(i,j)", y="Subject") +
guides(color=FALSE) +
scale_x_continuous(breaks = c(14,53), labels = c("Low Memory", "High Memory")) +
scale_y_discrete(breaks = c(14,53), labels = c("Low Memory", "High Memory")) +
theme(plot.title = element_text(hjust = 0.5, size=28, margin=margin(0,0,10,0), face="plain"),
axis.text.x = element_text(hjust = 0.5, size=18), axis.ticks.x = element_blank(),
axis.line.x = element_blank(), axis.title.x = element_text(hjust = 0.5, size=22),
axis.text.y = element_text(hjust = 0.5, size=18, angle=90, vjust=-4), axis.ticks.y = element_blank(),
axis.line.y = element_blank(), axis.title.y = element_text(hjust = 0.5, size=22, vjust=-4),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"),
plot.tag = element_text(size = 38, face = "bold"),
legend.text = element_text(size=14),
legend.title = element_text(size=18, margin = margin(0,0,5,0)),
legend.key.width = unit(0.5,"cm"), legend.key.height = unit(1,"cm"))
Run Intersubject RSA with permutation testing:
#### ---------- by Module ------------- #####
plots.images = list()
for (m in 1:length(modules)) {
# brain RDM for this module
this.brain <- module.RDMs.Time[,,m]
# correlate lower triangles of brain and behavior RDMs
my.cor <- cor(this.brain[unique.idx],this.behav[unique.idx], method="spearman")
# store null distribution of brain-behav correlations
perm.cors <- array(NA,c(1,nIter))
for (i in 1:nIter) {
this.order <- sample(c(1:nrow(this.brain)))
brain.shuffled <- this.brain[this.order,this.order] #shuffled subj labels on brain matrix
perm.cors[i] <- cor(brain.shuffled[unique.idx],this.behav[unique.idx], method="spearman")
}
perm.cors <- data.frame(t(perm.cors))
colnames(perm.cors) <- 'Spearman'
### plot null (permutation cors), making actual cor
plots.images[[m]] <- ggplot(perm.cors, aes(x=Spearman, y=..count..)) +
geom_histogram(binwidth = .005, fill="gray60", color="gray60") +
ggtitle(modules[m]) +
geom_vline(xintercept = my.cor, linetype=1, size=2, color=module.colors[m]) +
geom_vline(xintercept = 0, linetype=2, size=1) +
scale_y_continuous(expand=c(0,0,.02,0)) +
coord_cartesian(xlim = c(-.2,.2)) + #limits scale while ensuring no values are removed
theme(plot.title = element_text(hjust = 0.5, size=24, margin=margin(0,0,30,0), face="plain"),
axis.line.x = element_line(color = "black", size = 1),
axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 16), axis.text.y = element_text(size = 16),
axis.title.y = element_text(size = 18, margin=margin(0,10,0,0)),
axis.title.x = element_text(size = 18, margin=margin(10,0,0,0)),
panel.background = element_blank(), legend.position="none",
plot.margin = margin(0.15, 0.15, 0.15, 0.15, "cm"))
### store p values and correlations (testing if > 0)
my.stats$Model[m+3] <- 'AnnaK'
my.stats$Module[m+3] <- modules[m]
my.stats$r[m+3] <- my.cor
my.stats$p[m+3] <- sum(perm.cors$Spearman > my.cor)/nIter
}
p4 <- ggarrange(plotlist = plots.images, ncol = 3) +
theme(plot.tag = element_text(size = 38, face = "bold"),
plot.margin = margin(0.25, 1, 0.25, 0.25, "cm")) +
labs(tag="f")
### show stats from all models above, adjusting for multiple comparisons
my.stats$p.adj <- p.adjust(my.stats$p, method="bonferroni")
kable(my.stats, caption = 'time-varying connectivity -to- episodic memory intersubject RSA stats')
Model | Module | r | p | p.adj |
---|---|---|---|---|
NN | Dorsal | 0.0304743 | 0.1518 | 0.9108 |
NN | Ventral | 0.0507050 | 0.0533 | 0.3198 |
NN | Ventral-Dorsal | 0.0066974 | 0.3745 | 1.0000 |
AnnaK | Dorsal | 0.0360143 | 0.1972 | 1.0000 |
AnnaK | Ventral | 0.1012396 | 0.0170 | 0.1020 |
AnnaK | Ventral-Dorsal | 0.0168685 | 0.3034 | 1.0000 |
Based on the significant relationship beteween Ventral time-varying connectivity and episodic memory (in terms of intersubject similarity), I am visualizing the mean time-varying connectivity of the Ventral PMN subsystem for 2 groups of subjects, split (median) based on their episodic memory scores.
# grab event transition windows just to overlay on plot
load("event_transitions.RData")
my.TR = 2.47
med.score <- median(behav.data$Episodic)
behav.data$Group <- ''
behav.data$Group[behav.data$Episodic < med.score] <- "Low"
behav.data$Group[behav.data$Episodic >= med.score] <- "High"
# assign behavioral groups to time-varying connectivity data
TV$Group <- ''
TV$Group[TV$Subject %in% as.character(behav.data$SubID[behav.data$Group == "Low"])] <- "Low"
TV$Group[TV$Subject %in% as.character(behav.data$SubID[behav.data$Group == "High"])] <- "High"
TV$Group <- as.factor(TV$Group)
# mean Ventral connectivity by memory group
TV.summary <- TV %>% group_by(Time,Module,Group) %>%
summarise(Mean = mean(Conn),
SE = se(Conn)) %>%
subset(Module == "Ventral") %>%
droplevels()
# plot
tv.plot <- ggplot(TV.summary) +
geom_rect(data = b.groups, aes(xmin=start*my.TR, xmax=end*my.TR, ymin=-Inf,ymax=Inf),
fill = 'gray90') +
scale_fill_manual(values = c("#0b56d9","#85aff9")) +
scale_color_manual(values = c("#0b56d9","#85aff9")) +
geom_ribbon(alpha=0.3, aes(x=Time*my.TR, fill=Group,
ymin=Mean-SE, ymax=Mean+SE), color=NA) +
geom_line(aes(x=Time*my.TR, y=Mean, color=Group), size=1.5) +
scale_y_continuous(expand=c(0,0,0,0), limits=c(.1,.55)) +
scale_x_continuous(expand = c(0,0,0,0)) +
guides(fill=FALSE) +
labs(x="Time (seconds)", y='Mean Connectivity', tag="g", color="Memory") +
theme(axis.line.x = element_line(color = "black", size = 1),
axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 18), axis.text.y = element_text(size = 18),
axis.title.y = element_text(size = 20), axis.title.x = element_text(size = 20),
panel.background = element_blank(),
plot.tag = element_text(size = 38, face="bold"),
legend.text = element_text(size=16),
legend.title = element_text(size=18, margin = margin(0,0,5,0)),
legend.key.size = unit(2,"line"), legend.margin = margin(0,0,0,0.25, "cm"),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"))
Combine plots:
behav.plots <- ggarrange(p1, p3, nrow=2)
permutation.plots <- ggarrange(p2, p4, tv.plot, nrow=3)
myPlot <- ggarrange(behav.plots, permutation.plots, ncol=2, widths=c(1,1.75)) + # add arrow to go from Ventral plots to TV connectivity for high vs. low memory
geom_segment(aes(x = 0.70, y = 0.34, xend = 0.70, yend = 0.26),
color ="black", size=1,
arrow = arrow(length = unit(0.4,"cm"),type = "closed"))
# add analysis schematic
analysis.plot <- ggdraw() +
draw_image("./methods-figs/method_5_fig.png") +
labs(tag="b") +
theme(plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"),
plot.tag = element_text(size = 38, face = "bold"))
top.plot <- ggarrange(meancor.plots, analysis.plot, ncol=2, widths=c(4,1))
myPlot <- ggarrange(top.plot, myPlot, nrow=2, heights=c(1,2))
plot(myPlot)
## save
ggsave('./joined-figs/intersubject-RSA_joined.pdf', plot = myPlot, device = "pdf", width=18, height=17, unit="in")
It appears as though the two groups (High vs. Low memory subjects) differ in terms of their change in Ventral connectivity strength over time… is this a significant difference?
* For each subject, I am calculating the correlation between time-varying connectivity and time, to test for a linear change. The mean correlation (fisher-z transformed) across subjects is tested against 0.
# mean Ventral connectivity by memory group
TV.summary <- TV %>% group_by(Subject,Module,Group) %>%
summarise(Z = fisherz(cor(Conn,Time))) %>%
subset(Module == "Ventral") %>%
droplevels()
# t.test against zero
ts <- data.frame(TV.summary) %>%
group_by(Group) %>%
rstatix::t_test(Z ~ 1, mu=0,
p.adjust.method = "none",
detailed=T)
kable(ts, format = "pandoc",
caption = "One sample t-test, mean within-subject correlation between Ventral time-varying connectivity and time")
Group | estimate | .y. | group1 | group2 | n | statistic | p | df | conf.low | conf.high | method | alternative |
---|---|---|---|---|---|---|---|---|---|---|---|---|
High | 0.3252922 | Z | 1 | null model | 35 | 5.3078279 | 0.0000068 | 34 | 0.2007453 | 0.4498390 | T-test | two.sided |
Low | 0.0024435 | Z | 1 | null model | 32 | 0.0387386 | 0.9690000 | 31 | -0.1262032 | 0.1310902 | T-test | two.sided |
# difference between groups?
ts <- data.frame(TV.summary) %>%
rstatix::t_test(
Z ~ Group,
detailed=T)
kable(ts, format = "pandoc",
caption = "Independent sample t-test between memory groups")
estimate | estimate1 | estimate2 | .y. | group1 | group2 | n1 | n2 | statistic | p | df | conf.low | conf.high | method | alternative |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0.3228486 | 0.3252922 | 0.0024435 | Z | High | Low | 35 | 32 | 3.670958 | 0.000492 | 64.636 | 0.1471882 | 0.4985091 | T-test | two.sided |
Plots for High vs. Low memory subjects for Dorsal and Ventral-to-Dorsal time-varying connectivity. No visible difference between subjects, in line with the non-significant relationship between intersubject similarity of time-varying connectivity and intersubject similarity of episodic memory.
### Dorsal ###
TV.summary <- TV %>% group_by(Time,Module,Group) %>%
summarise(Mean = mean(Conn),
SE = se(Conn)) %>%
subset(Module == "Dorsal") %>%
droplevels()
# plot
core.plot <- ggplot(TV.summary) +
geom_rect(data = b.groups, aes(xmin=start*my.TR, xmax=end*my.TR, ymin=-Inf,ymax=Inf),
fill = 'gray90') +
scale_fill_manual(values = c("#edc004","#fde78c")) +
scale_color_manual(values = c("#edc004","#fde78c")) +
geom_ribbon(alpha=0.3, aes(x=Time*my.TR, fill=Group,
ymin=Mean-SE, ymax=Mean+SE), color=NA) +
geom_line(aes(x=Time*my.TR, y=Mean, color=Group), size=1.5) +
scale_y_continuous(expand=c(0,0,0,0), limits=c(.05,.45)) +
scale_x_continuous(expand = c(0,0,0,0)) +
guides(fill=FALSE) +
ggtitle("Dorsal: High vs. Low Memory") +
labs(x="Time (seconds)", y='Mean Connectivity', color="Memory") +
theme(plot.title = element_text(hjust = 0.5, size=24, margin=margin(0,0,30,0), face="plain"),
axis.line.x = element_line(color = "black", size = 1),
axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 16), axis.text.y = element_text(size = 16),
axis.title.y = element_text(size = 18), axis.title.x = element_text(size = 18),
panel.background = element_blank(),
legend.text = element_text(size=14),
legend.title = element_text(size=16, margin = margin(0,0,5,0)),
legend.key.size = unit(2,"line"), legend.margin = margin(0,0,0,0.25, "cm"),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"))
### Ventral-to-Dorsal ###
TV.summary <- TV %>% group_by(Time,Module,Group) %>%
summarise(Mean = mean(Conn),
SE = se(Conn)) %>%
subset(Module == "Ventral-Dorsal") %>%
droplevels()
# plot
cv.plot <- ggplot(TV.summary) +
geom_rect(data = b.groups, aes(xmin=start*my.TR, xmax=end*my.TR, ymin=-Inf,ymax=Inf),
fill = 'gray90') +
scale_fill_manual(values = c("#44dbf2","#bcf2fa")) +
scale_color_manual(values = c("#44dbf2","#bcf2fa")) +
geom_ribbon(alpha=0.3, aes(x=Time*my.TR, fill=Group,
ymin=Mean-SE, ymax=Mean+SE), color=NA) +
geom_line(aes(x=Time*my.TR, y=Mean, color=Group), size=1.5) +
scale_y_continuous(expand=c(0,0,0,0), limits=c(.05,.45)) +
scale_x_continuous(expand = c(0,0,0,0)) +
guides(fill=FALSE) +
ggtitle("Ventral-Dorsal: High vs. Low Memory") +
labs(x="Time (seconds)", y='Mean Connectivity', color="Memory") +
theme(plot.title = element_text(hjust = 0.5, size=24, margin=margin(0,0,30,0), face="plain"),
axis.line.x = element_line(color = "black", size = 1),
axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 16), axis.text.y = element_text(size = 16),
axis.title.y = element_text(size = 18), axis.title.x = element_text(size = 18),
panel.background = element_blank(),
legend.text = element_text(size=14),
legend.title = element_text(size=16, margin = margin(0,0,5,0)),
legend.key.size = unit(2,"line"), legend.margin = margin(0,0,0,0.25, "cm"),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"))
ggarrange(core.plot, cv.plot, nrow=2)
As a control analysis, I’m testing whether a relationship between the PMN subsystems and episodic memory exists when considering time-varying activity rather than connectivity.
#### initiate stats data frame for NN and Anna K models
my.stats <- data.frame(array(0,c(4,4)))
colnames(my.stats) <- c('Model','Module','r','p')
ord <- episodic.ord
### load in activity time series
allData.1 = read.csv('./Discovery/PM_node_timeseries_Discovery.csv', header = TRUE)
allData.2 = read.csv('./Replication/PM_node_timeseries_Replication.csv', header = TRUE)
allData <- rbind(allData.1, allData.2)
#filter by subjects who have behavioral data and match order to behavioral data
sub.idx <- allData$Subject %in% behav.data$SubID
allData <- allData[sub.idx,]
allData <- allData[order(as.character(allData$Subject)),]
allData$Subject=factor(allData$Subject, levels=as.character(behav.data$SubID))
# add Module information
allData$Module <- ''
allData$Module[allData$Node == "PHC" | allData$Node == "RSC" | allData$Node == "pAG"] <- "Ventral"
allData$Module[allData$Node == "Hipp" | allData$Node == "MPFC" | allData$Node == "PCC" |
allData$Node == "Prec" | allData$Node == "aAG"] <- "Dorsal"
allData$Module=as.factor(allData$Module)
# average activity by module
module.activity <- allData %>% group_by(Subject, Time, Module) %>%
summarise(Activity = mean(Value))
### calculate subjxsubj correlation matrices for time-varying activity
activity.RDMs.Time <- array(0,c(NSubs,NSubs,2))
plots.images = list()
for (m in 1:2) {
module_data <- subset(module.activity, Module == modules[m]) %>%
spread(Subject, Activity) %>%
droplevels()
# which columns are subjects?
subcols <- grep('sub-',colnames(module_data))
# correlate subject time series, taking **dissimilarity (1- pearson correlation)**
module_matrix <- 1 - cor(module_data[,subcols])
diag(module_matrix) <- NA
# catch to make sure subID col names are in same order as behavData subIDs
check = setdiff(as.character(behav.data$SubID),colnames(module_matrix))
if (!is_empty(check)) { stop('SubID order in brain RDM does not match behavioral data')}
## store (in behav subject order)
activity.RDMs.Time[,,m] <- module_matrix
#sort by behavioral score for visualization
module.matrix.sort <- data.frame(module_matrix[ord,ord])
colnames(module.matrix.sort) <- 1:nrow(module.matrix.sort)
module.matrix.sort$Subject <- 1:nrow(module.matrix.sort)
plots.images[[m]] <- ggplot(melt(module.matrix.sort,"Subject"),
aes(Subject, variable, fill=value)) +
geom_tile() +
scale_fill_gradientn(colors = heat.colors(10), na.value = "gray80",
guide = guide_colorbar(frame.colour = "black"),
limits=c(0,1.5)) +
ggtitle(modules[m]) + labs(fill="Dissimilarity", y="Subject") +
scale_x_continuous(breaks = c(12,55), labels = c("Low Memory", "High Memory")) +
scale_y_discrete(breaks = c(12,55), labels = c("Low Memory", "High Memory")) +
theme(plot.title = element_text(hjust = 0.5, size=26, margin=margin(0,0,10,0), face="plain"),
axis.text.x = element_text(hjust = 0.5, size=16), axis.ticks.x = element_blank(),
axis.line.x = element_blank(), axis.title.x = element_text(hjust = 0.5, size=18),
axis.text.y = element_text(hjust = 0.5, size=16, angle=90, vjust=-4), axis.ticks.y = element_blank(),
axis.line.y = element_blank(), axis.title.y = element_text(hjust = 0.5, size=18, vjust=-4),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"))
}
ggarrange(plotlist = plots.images, ncol = 2)
colnames(activity.RDMs.Time) <- colnames(module_matrix)
rownames(activity.RDMs.Time) <- rownames(module_matrix)
# catch to make sure brain RDM subject order is the same as behavior RDM subject order
check = setdiff(colnames(behav.RDM.matrix.NN),colnames(activity.RDMs.Time))
if (!is_empty(check)) { stop('SubID order in brain RDM does not match behavior RDM')}
this.behav <- behav.RDM.matrix.NN
#### ---------- by Module ------------- #####
plots.images = list()
for (m in 1:2) {
# brain RDM for this module
this.brain <- activity.RDMs.Time[,,m]
# correlate lower triangles of brain and behavior RDMs
my.cor <- cor(this.brain[unique.idx],this.behav[unique.idx], method="spearman")
# store null distribution of brain-behav correlations
perm.cors <- array(NA,c(1,nIter))
for (i in 1:nIter) {
this.order <- sample(c(1:nrow(this.brain)))
brain.shuffled <- this.brain[this.order,this.order] #shuffled subj labels on brain matrix
perm.cors[i] <- cor(brain.shuffled[unique.idx],this.behav[unique.idx], method="spearman")
}
perm.cors <- data.frame(t(perm.cors))
colnames(perm.cors) <- 'Spearman'
### plot null (permutation cors), making actual cor
plots.images[[m]] <- ggplot(perm.cors, aes(x=Spearman, y=..count..)) +
geom_histogram(binwidth = .005, fill="gray60", color="gray60") +
ggtitle(modules[m]) +
geom_vline(xintercept = my.cor, linetype=1, size=2, color=module.colors[m]) +
geom_vline(xintercept = 0, linetype=2, size=1) +
scale_y_continuous(expand=c(0,0,.02,0)) +
coord_cartesian(xlim = c(-.3,.3)) +
theme(plot.title = element_text(hjust = 0.5, size=24, margin=margin(0,0,30,0), face="plain"),
axis.line.x = element_line(color = "black", size = 1),
axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 16), axis.text.y = element_text(size = 16),
axis.title.y = element_text(size = 18, margin=margin(0,10,0,0)),
axis.title.x = element_text(size = 16, margin=margin(10,0,0,0)),
panel.background = element_blank(), legend.position="none",
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"))
### store p values and correlations (testing if > 0)
my.stats$Model[m] <- 'NN'
my.stats$Module[m] <- modules[m]
my.stats$r[m] <- my.cor
my.stats$p[m] <- sum(perm.cors$Spearman > my.cor)/nIter
}
p1 <- ggarrange(plotlist = plots.images, ncol = 2) +
ggtitle("Nearest Neighbor") +
theme(plot.title = element_text(hjust = 0.5, size=26,
margin=margin(0,0,10,0), face="plain"),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"))
# catch to make sure brain RDM subject order is the same as behavior RDM subject order
check = setdiff(colnames(behav.RDM.matrix.AK),colnames(activity.RDMs.Time))
if (!is_empty(check)) { stop('SubID order in brain RDM does not match behavior RDM')}
this.behav <- behav.RDM.matrix.AK
#### ---------- by Module ------------- #####
plots.images = list()
for (m in 1:2) {
# brain RDM for this module
this.brain <- activity.RDMs.Time[,,m]
# correlate lower triangles of brain and behavior RDMs
my.cor <- cor(this.brain[unique.idx],this.behav[unique.idx], method="spearman")
# store null distribution of brain-behav correlations
perm.cors <- array(NA,c(1,nIter))
for (i in 1:nIter) {
this.order <- sample(c(1:nrow(this.brain)))
brain.shuffled <- this.brain[this.order,this.order] #shuffled subj labels on brain matrix
perm.cors[i] <- cor(brain.shuffled[unique.idx],this.behav[unique.idx], method="spearman")
}
perm.cors <- data.frame(t(perm.cors))
colnames(perm.cors) <- 'Spearman'
### plot null (permutation cors), making actual cor
plots.images[[m]] <- ggplot(perm.cors, aes(x=Spearman, y=..count..)) +
geom_histogram(binwidth = .005, fill="gray60", color="gray60") +
ggtitle(modules[m]) +
geom_vline(xintercept = my.cor, linetype=1, size=2, color=module.colors[m]) +
geom_vline(xintercept = 0, linetype=2, size=1) +
scale_y_continuous(expand=c(0,0,.02,0)) +
coord_cartesian(xlim = c(-.3,.3)) +
theme(plot.title = element_text(hjust = 0.5, size=24, margin=margin(0,0,30,0), face="plain"),
axis.line.x = element_line(color = "black", size = 1),
axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 16), axis.text.y = element_text(size = 16),
axis.title.y = element_text(size = 18, margin=margin(0,10,0,0)),
axis.title.x = element_text(size = 16, margin=margin(10,0,0,0)),
panel.background = element_blank(), legend.position="none",
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"))
### store p values and correlations (testing if > 0)
my.stats$Model[m+2] <- 'AnnaK'
my.stats$Module[m+2] <- modules[m]
my.stats$r[m+2] <- my.cor
my.stats$p[m+2] <- sum(perm.cors$Spearman > my.cor)/nIter
}
p2 <- ggarrange(plotlist = plots.images, ncol = 2) +
ggtitle("Anna K") +
theme(plot.title = element_text(hjust = 0.5, size=26,
margin=margin(0,0,10,0), face="plain"),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"))
### show stats from all models above, adjusting for multiple comparisons
my.stats$p.adj <- p.adjust(my.stats$p, method="bonferroni")
kable(my.stats, caption = 'time-varying activity -to- episodic memory intersubject RSA stats')
Model | Module | r | p | p.adj |
---|---|---|---|---|
NN | Dorsal | 0.0281398 | 0.2532 | 1.0000 |
NN | Ventral | -0.0035516 | 0.5206 | 1.0000 |
AnnaK | Dorsal | 0.0782339 | 0.1441 | 0.5764 |
AnnaK | Ventral | 0.0705806 | 0.1911 | 0.7644 |
Plot:
myPlot <- ggarrange(p1, p2, ncol = 2)
plot(myPlot)
As a control analysis, I’m testing if the relationship between PMN time-varying connectivity and memory is selective to episodic memory by using an separate measure from the same task – priming.
#### initiate stats data frame for NN and Anna K models
my.stats <- data.frame(array(0,c(length(modules)*2,4)))
colnames(my.stats) <- c('Model','Module','r','p')
ord <- priming.ord
#### BEHAVIOR RDM #######
priming.scores <- t(spread(subset(behav.data, select=-c(Episodic,Group)), SubID, Priming))
behav.RDM.matrix.NN <- as.matrix(dist(priming.scores, method='euclidean')) #dist takes distance between rows (subjects' scores)
diag(behav.RDM.matrix.NN) <- NA
# catch to make sure brain RDM subject order is the same as behavior RDM subject order
check = setdiff(colnames(behav.RDM.matrix.NN),colnames(module.RDMs.Time))
if (!is_empty(check)) { stop('SubID order in brain RDM does not match behavior RDM')}
# store in subject order for RDM comparison
this.behav <- behav.RDM.matrix.NN
## plot sorting by behavioral score for visualization
behav.RDM.matrix.sort <- behav.RDM.matrix.NN[ord,ord]
behav.RDM <- data.frame(behav.RDM.matrix.sort)
colnames(behav.RDM) <- 1:nrow(behav.RDM)
behav.RDM$Subject <- 1:nrow(behav.RDM)
p1 <- ggplot(melt(behav.RDM, "Subject"),
aes(Subject, variable, fill=value, color=value)) +
geom_tile() +
scale_fill_gradientn(limits=c(0,.5),
colors = heat.colors(10), na.value = "gray80",
guide = guide_colorbar(frame.colour = "black")) +
scale_color_gradientn(limits=c(0,.5),
colors = heat.colors(10), na.value = "gray80",
guide = guide_colorbar(frame.colour = "black")) +
ggtitle('Nearest Neighbor') +
labs(tag="a", fill="abs(i-j)", y="Subject") +
guides(color=FALSE) +
scale_x_continuous(breaks = c(12,55), labels = c("Low Memory", "High Memory")) +
scale_y_discrete(breaks = c(12,55), labels = c("Low Memory", "High Memory")) +
theme(plot.title = element_text(hjust = 0.5, size=26, margin=margin(0,0,10,0), face="plain"),
axis.text.x = element_text(hjust = 0.5, size=16), axis.ticks.x = element_blank(),
axis.line.x = element_blank(), axis.title.x = element_text(hjust = 0.5, size=18),
axis.text.y = element_text(hjust = 0.5, size=16, angle=90, vjust=-4), axis.ticks.y = element_blank(),
axis.line.y = element_blank(), axis.title.y = element_text(hjust = 0.5, size=18, vjust=-4),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"),
plot.tag = element_text(size = 32, face = "bold"),
legend.text = element_text(size=14),
legend.title = element_text(size=18, margin = margin(0,0,5,0)),
legend.key.width = unit(0.5,"cm"), legend.key.height = unit(1,"cm"))
#### ---------- by Module ------------- #####
plots.images = list()
for (m in 1:length(modules)) {
# brain RDM for this module
this.brain <- module.RDMs.Time[,,m]
# correlate lower triangles of brain and behavior RDMs
my.cor <- cor(this.brain[unique.idx],this.behav[unique.idx], method="spearman")
# store null distribution of brain-behav correlations
perm.cors <- array(NA,c(1,nIter))
for (i in 1:nIter) {
this.order <- sample(c(1:nrow(this.brain)))
brain.shuffled <- this.brain[this.order,this.order] #shuffled subj labels on brain matrix
perm.cors[i] <- cor(brain.shuffled[unique.idx],this.behav[unique.idx], method="spearman")
}
perm.cors <- data.frame(t(perm.cors))
colnames(perm.cors) <- 'Spearman'
### plot null (permutation cors), making actual cor
plots.images[[m]] <- ggplot(perm.cors, aes(x=Spearman, y=..count..)) +
geom_histogram(binwidth = .005, fill="gray60", color="gray60") +
ggtitle(modules[m]) +
geom_vline(xintercept = my.cor, linetype=1, size=2, color=module.colors[m]) +
geom_vline(xintercept = 0, linetype=2, size=1) +
scale_y_continuous(expand=c(0,0,.02,0)) +
coord_cartesian(xlim = c(-.2,.2)) + #limits scale while ensuring no values are removed
theme(plot.title = element_text(hjust = 0.5, size=24, margin=margin(0,0,30,0), face="plain"),
axis.line.x = element_line(color = "black", size = 1),
axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 16), axis.text.y = element_text(size = 16),
axis.title.y = element_text(size = 18, margin=margin(0,10,0,0)),
axis.title.x = element_text(size = 18, margin=margin(10,0,0,0)),
panel.background = element_blank(), legend.position="none",
plot.margin = margin(0.15, 0.15, 0.15, 0.15, "cm"))
### store p values and correlations (testing if > 0)
my.stats$Model[m] <- 'NN'
my.stats$Module[m] <- modules[m]
my.stats$r[m] <- my.cor
my.stats$p[m] <- sum(perm.cors$Spearman > my.cor)/nIter
}
p2 <- ggarrange(plotlist = plots.images, ncol = 3) +
theme(plot.tag = element_text(size = 32, face = "bold"),
plot.margin = margin(2, 0.25, 1, 0.25, "cm")) +
labs(tag="c")
#### BEHAVIOR RDM #######
behav.RDM.matrix.AK <- array(NA,c(NSubs,NSubs))
colnames(behav.RDM.matrix.AK) <- behav.data$SubID
rownames(behav.RDM.matrix.AK) <- behav.data$SubID
# calculate Anna K dissimilarity -- i.e. max score - (min(i,j))
for (x in 1:NSubs) {
for (y in 1:NSubs) {
behav.RDM.matrix.AK[x,y] <- max(behav.data$Priming) - (min(c(behav.data$Priming[x],
behav.data$Priming[y])))
}
}
diag(behav.RDM.matrix.AK) <- NA
# catch to make sure brain RDM subject order is the same as behavior RDM subject order
check = setdiff(colnames(behav.RDM.matrix.AK),colnames(module.RDMs.Time))
if (!is_empty(check)) { stop('SubID order in brain RDM does not match behavior RDM')}
# store in subject order
this.behav <- behav.RDM.matrix.AK
## plot sorting by behavioral score
behav.RDM.matrix.sort <- behav.RDM.matrix.AK[ord,ord]
behav.RDM <- data.frame(behav.RDM.matrix.sort)
colnames(behav.RDM) <- 1:nrow(behav.RDM)
behav.RDM$Subject <- 1:nrow(behav.RDM)
p3 <- ggplot(melt(behav.RDM, "Subject"),
aes(Subject, variable, fill=value, color=value)) +
geom_tile() +
scale_fill_gradientn(limits=c(0,.5),
colors = heat.colors(10), na.value = "gray80",
guide = guide_colorbar(frame.colour = "black")) +
scale_color_gradientn(limits=c(0,.5),
colors = heat.colors(10), na.value = "gray80",
guide = guide_colorbar(frame.colour = "black")) +
ggtitle('Anna K') +
labs(tag="b", fill="max-\nmin(i,j)", y="Subject") +
guides(color=FALSE) +
scale_x_continuous(breaks = c(12,55), labels = c("Low Memory", "High Memory")) +
scale_y_discrete(breaks = c(12,55), labels = c("Low Memory", "High Memory")) +
theme(plot.title = element_text(hjust = 0.5, size=26, margin=margin(0,0,10,0), face="plain"),
axis.text.x = element_text(hjust = 0.5, size=16), axis.ticks.x = element_blank(),
axis.line.x = element_blank(), axis.title.x = element_text(hjust = 0.5, size=18),
axis.text.y = element_text(hjust = 0.5, size=16, angle=90, vjust=-4), axis.ticks.y = element_blank(),
axis.line.y = element_blank(), axis.title.y = element_text(hjust = 0.5, size=18, vjust=-4),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm"),
plot.tag = element_text(size = 32, face = "bold"),
legend.text = element_text(size=14),
legend.title = element_text(size=18, margin = margin(0,0,5,0)),
legend.key.width = unit(0.5,"cm"), legend.key.height = unit(1,"cm"))
#### ---------- by Module ------------- #####
plots.images = list()
for (m in 1:length(modules)) {
# brain RDM for this module
this.brain <- module.RDMs.Time[,,m]
# correlate lower triangles of brain and behavior RDMs
my.cor <- cor(this.brain[unique.idx],this.behav[unique.idx], method="spearman")
# store null distribution of brain-behav correlations
perm.cors <- array(NA,c(1,nIter))
for (i in 1:nIter) {
this.order <- sample(c(1:nrow(this.brain)))
brain.shuffled <- this.brain[this.order,this.order] #shuffled subj labels on brain matrix
perm.cors[i] <- cor(brain.shuffled[unique.idx],this.behav[unique.idx], method="spearman")
}
perm.cors <- data.frame(t(perm.cors))
colnames(perm.cors) <- 'Spearman'
### plot null (permutation cors), making actual cor
plots.images[[m]] <- ggplot(perm.cors, aes(x=Spearman, y=..count..)) +
geom_histogram(binwidth = .005, fill="gray60", color="gray60") +
ggtitle(modules[m]) +
geom_vline(xintercept = my.cor, linetype=1, size=2, color=module.colors[m]) +
geom_vline(xintercept = 0, linetype=2, size=1) +
scale_y_continuous(expand=c(0,0,.02,0)) +
coord_cartesian(xlim = c(-.2,.2)) + #limits scale while ensuring no values are removed
theme(plot.title = element_text(hjust = 0.5, size=24, margin=margin(0,0,30,0), face="plain"),
axis.line.x = element_line(color = "black", size = 1),
axis.line.y = element_line(color = "black", size = 1),
axis.text.x = element_text(size = 16), axis.text.y = element_text(size = 16),
axis.title.y = element_text(size = 18, margin=margin(0,10,0,0)),
axis.title.x = element_text(size = 18, margin=margin(10,0,0,0)),
panel.background = element_blank(), legend.position="none",
plot.margin = margin(0.15, 0.15, 0.15, 0.15, "cm"))
### store p values and correlations (testing if > 0)
my.stats$Model[m+3] <- 'AnnaK'
my.stats$Module[m+3] <- modules[m]
my.stats$r[m+3] <- my.cor
my.stats$p[m+3] <- sum(perm.cors$Spearman > my.cor)/nIter
}
p4 <- ggarrange(plotlist = plots.images, ncol = 3) +
theme(plot.tag = element_text(size = 32, face = "bold"),
plot.margin = margin(2, 0.25, 1, 0.25, "cm")) +
labs(tag="d")
### show stats from all models above, adjusting for multiple comparisons
my.stats$p.adj <- p.adjust(my.stats$p, method="bonferroni")
kable(my.stats, caption = 'time-varying connectivity -to- priming intersubject RSA stats')
Model | Module | r | p | p.adj |
---|---|---|---|---|
NN | Dorsal | 0.0369556 | 0.1241 | 0.7446 |
NN | Ventral | -0.0195163 | 0.7119 | 1.0000 |
NN | Ventral-Dorsal | 0.0185327 | 0.2372 | 1.0000 |
AnnaK | Dorsal | 0.0527119 | 0.1134 | 0.6804 |
AnnaK | Ventral | -0.0453462 | 0.8486 | 1.0000 |
AnnaK | Ventral-Dorsal | -0.0584954 | 0.9658 | 1.0000 |
Plot:
behav.plots <- ggarrange(p1, p3, nrow=2)
permutation.plots <- ggarrange(p2, p4, nrow=2)
myPlot <- ggarrange(behav.plots, permutation.plots, ncol=2, widths=c(1.5,3))
plot(myPlot)