---
title: "LCCC1520"
output: html_document
---
  
  ```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

#Total runtime: ~10min

#Load packages

```{r}

#install.packages('ggplot2')
#install.packages('dplyr')
#install.packages('ggpubr')
# if (!require("BiocManager", quietly = TRUE))
#   install.packages("BiocManager")
# BiocManager::install("maftools",force=TRUE)# install.packages("remotes")
# remotes::install_github("Displayr/flipPlots")
#install.packages('pROC')
#install.packages('ggrepel')
#install.packages('gplots')
#install.packages('ggcorrplot')
#install.packageS('scales')
#install.packageS('plyr')
#install.packages('reshape2')
#install.packages('ggh4x')
#install.packageS('ggnewscale')
#install.packages('glmnet')
#install.packages('caret')
#install.packages('caTools')
# install.packages('matrixStats')
#install.packages('survival')
#install.packages('survminer')
#install.packages('ggpmisc')
#install.packages('matrixStats')

library(ggplot2)
library(plyr)
library(dplyr)
library(maftools)
library(flipPlots)
library(ggpubr)
library(ggrepel)
library(pROC)
library(ggcorrplot)
library(gplots)
library(scales)
library(reshape2)
library(ggh4x)
library(ggnewscale)
library(glmnet)
library(caret)
library(caTools)
library(survival)
library(survminer)
library(ggpmisc)
library(matrixStats)
library(ggrepel)

```


#Figure 1

```{r}


clin = read.csv('Clinical1520.csv')
clin$response = 'NR'
clin$response[clin$Pathologic_Responder=='Yes']='PR'
clin$response[clin$complete_response=='Yes']='CR'

df_t_stage=data.frame(table(clin$response,substr(clin$Clinical_T_stage,1,2)))
df_t_stage=df_t_stage[df_t_stage$Freq!=0,]

#Figure 1B
ggplot(df_t_stage, aes(x =Var1, y = Freq, fill = Var2)) +
  geom_col(position = position_fill(reverse = TRUE)) +
  scale_fill_manual(values=c('pink','darkred','lightblue'),name='Clinical\nT stage')+
  geom_text(aes(y = c(11/28,11/34,6/16,11/14+1/14,11/17+3/17,6.5/8,27/28,15/16), label = Freq)) +
  theme_bw()+
  theme(panel.grid=element_blank())+
  xlab('p=0.361')+ylab('Proportion')+theme(axis.title=element_text(face='bold'))


df_ecog=data.frame(table(clin$response,substr(clin$ECOG_Performance_Status,1,1)))
df_ecog=df_ecog[df_ecog$Freq!=0,]

#Figure 1C
ggplot(df_ecog, aes(x =Var1, y = Freq, fill = Var2)) +
  geom_col(position = position_fill(reverse = TRUE)) +
  scale_fill_manual(values=c('purple','lavender'),name='Baseline\nECOG\nPerformance\nStatus')+
  geom_text(aes(y = c(5/14,6.5/17,2.5/8,12/14,15/17,6.5/8), label = Freq)) +
  theme_bw()+
  theme(panel.grid=element_blank())+
  xlab('p=0.897')+ylab('Proportion')+theme(axis.title=element_text(face='bold'))

clin$Adverse_Event='None'
clin$Adverse_Event[clin$Reason_chemotherapy_ended=="Adverse events / Side effects (specify in Comments)"]='Adverse Event'
clin$Adverse_Event

df_adverse=data.frame(table(clin$response,clin$Adverse_Event))
df_adverse=df_adverse[df_adverse$Freq!=0,]
df_adverse$Var1 = factor(df_adverse$Var1,levels=c('CR','PR','NR'))

fisher.test(table(clin$response,substr(clin$Adverse_Event,1,1)))

ggplot(df_adverse, aes(x =Var2, y = Freq, fill = Var1)) +
  geom_col(position = position_fill(reverse = TRUE)) +
  scale_fill_manual(values=c('orange','yellow','brown'),name='Clinical\nResponse')+
  geom_text(aes(y = c(2/12,8/12,5/27,14/27,22.5/27), label = Freq)) +
  theme_bw()+
  theme(panel.grid=element_blank())+
  xlab('p=0.058')+ylab('Proportion')+theme(axis.title=element_text(face='bold'))


```

#Figure 2

```{r}

#Figure 2A: TMB

tmb = read.csv('LCCC1520_TMB.csv')
tmb = tmb[-c(17,31),] #remove old samples that have been re-sequenced
tmb$Patient = substr(tmb$Sample_ID,1,3)
tmbpre = tmb[substr(tmb$Sample_ID,6,6)=='r',] #pre-treatment TMB
tmbpost = tmb[substr(tmb$Sample_ID,6,6)=='o',] #post-treatment TMB

#only including samples with matched pre and post
tmb_pre_post = inner_join(tmbpre,tmbpost,by="Patient") #combine pre and post,
colnames(tmb_pre_post) = c('Sample_pre','TMB_pre','Patient','Sample_post','TMB_post')

#Remove complete responders
clinical = read.csv('Clinical1520.csv')
clinical$Patient = as.character(clinical$ID)
complete_response = data.frame(clinical$Patient,clinical$complete_response)
colnames(complete_response) = c('Patient','complete_response')
tmbpp_clin = full_join(tmb_pre_post,complete_response,by="Patient")
tmbpp_no_CR = na.omit(tmbpp_clin[tmbpp_clin$complete_response=='No',])

#Plot TMB
plot_tmb <- data.frame(`Pre.Tx` = tmbpp_no_CR$TMB_pre, `Post.Tx` = tmbpp_no_CR$TMB_post)
ggpaired(plot_tmb, cond1 = "Pre.Tx", cond2 = "Post.Tx",
         fill = "condition",
         point.size = 0,outline='black',outlier.shape='')+
  geom_point(size=4,alpha=0.4)+
  stat_compare_means(paired = TRUE,comparisons = list(c('Pre.Tx','Post.Tx')),
                     aes(label = ..p.format..),
                     label.x = 1.5,size=5)+ 
  theme(legend.position = "none")+ylab('TMB')+xlab('')+
  ggtitle('Non-pCR patients')+scale_fill_manual(values=c('darkgreen','maroon'))+
  theme(plot.title = element_text(face="bold"),
        axis.title.y = element_text(face="bold"),
        axis.text.x = element_text(face="bold"),
        panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  scale_x_discrete(breaks = c('Pre.Tx','Post.Tx'),
                   labels=c("Pre-Treatment", "Post-Treatment"))


#Figure 2B-D: Oncoplots

#read in .maf file
maf1520 = read.maf(maf = 'lccc1520.somatic_filtered_merged.maf')

#protein-coding mutations only
maf1520 = subsetMaf(maf1520,query = "BIOTYPE=='protein_coding'")

#Cadabra indel quality >10.5, 
#Mutect2 indel quality >6.8 or SNV quality >9.2,
#Strelka2 indel quality >15.2 or SNV quality >19.7
maf1520 = subsetMaf(maf1520,query = "(CADABRA_QUAL>10.5)|
                 (MUTECT2_TLOD > 9.2) | 
                 (Variant_Type %in% c('INS','DEL') & MUTECT2_TLOD>6.8)|
                 (STRELKA2_SomaticEVS > 19.7) | 
                 (Variant_Type %in% c('INS','DEL') & STRELKA2_SomaticEVS>15.2)")

#Remaining variants required at least 5 supporting reads and a minimum read depth of 40,
#or 10 supporting reads and minimum read depth of 80 if MAF <5%
maf1520 = subsetMaf(maf1520,query = "((t_alt_count/(t_ref_count))>=0.05 &
                 t_alt_count>=5 & t_depth>=40)|
                 ((t_alt_count/(t_ref_count))<0.05 &
                 t_alt_count>=10 & t_depth>=80)")

#Variants with a MAF>5% in normal tissue were dropped...
maf1520 = subsetMaf(maf1520,query = "n_alt_count/(n_ref_count)<=0.05")

#...as were variants appearing at rates above 1% in any subpopulation in either
#GnomAD...
maf1520 = subsetMaf(maf1520,query = "gnomAD_AFR_AF<=0.01 | is.na(gnomAD_AFR_AF)")
maf1520 = subsetMaf(maf1520,query = "gnomAD_ASJ_AF<=0.01| is.na(gnomAD_ASJ_AF)")
maf1520 = subsetMaf(maf1520,query = "gnomAD_FIN_AF<=0.01| is.na(gnomAD_FIN_AF)")
maf1520 = subsetMaf(maf1520,query = "gnomAD_NFE_AF<=0.01| is.na(gnomAD_NFE_AF)")
maf1520 = subsetMaf(maf1520,query = "gnomAD_OTH_AF<=0.01| is.na(gnomAD_OTH_AF)")
maf1520 = subsetMaf(maf1520,query = "gnomAD_SAS_AF<=0.01| is.na(gnomAD_SAS_AF)")

#...or 1000 Genomes databases
maf1520 = subsetMaf(maf1520,query = "AFR_AF<=0.01| is.na(AFR_AF)")
maf1520 = subsetMaf(maf1520,query = "AMR_AF<=0.01| is.na(AMR_AF)")
maf1520 = subsetMaf(maf1520,query = "ASN_AF<=0.01| is.na(ASN_AF)")
maf1520 = subsetMaf(maf1520,query = "EAS_AF<=0.01| is.na(EAS_AF)")
maf1520 = subsetMaf(maf1520,query = "EUR_AF<=0.01| is.na(EUR_AF)")
maf1520 = subsetMaf(maf1520,query = "SAS_AF<=0.01| is.na(SAS_AF)")
maf1520 = subsetMaf(maf1520,query = "AA_AF<=0.01| is.na(AA_AF)")
maf1520 = subsetMaf(maf1520,query = "EA_AF<=0.01| is.na(EA_AF)")

#To counter FFPE artifacts, C>T and G>A substitutions required a minimum MAF of 10%
maf1520 = subsetMaf(maf1520,query = "n_alt_count/n_ref_count + 1*(!((Reference_Allele == 'C' &
             (Tumor_Seq_Allele1=='T'&Tumor_Seq_Allele2=='T')) |
  (Reference_Allele == 'G' &
     (Tumor_Seq_Allele1=='A'&Tumor_Seq_Allele2=='A'))))>=0.1")

#Cosmic Tier 1 bladder listing genes
genelist = c('TP53','KDM6A','ERBB3','TSC1',
             'STAG2','CDKN2A','NOTCH1','FGFR3',
             'TBL1XR1','ETV6')

#remove old samples with poor QC that have been re-sequenced
maf1520 = subsetMaf(maf1520,tsb = names(table(maf1520@data$Tumor_Sample_Barcode))[-c(17,31)])



maf1520@clinical.data$Patient= substr(maf1520@clinical.data$Tumor_Sample_Barcode,1,3)
#Post-treatment non-pCR samples

#Matched pre-and post-treatment samples

#Label pre and post timepoints
maf1520@clinical.data$Timepoint = substr(maf1520@clinical.data$Tumor_Sample_Barcode,5,7)
maf1520@clinical.data$Timepoint[maf1520@clinical.data$Timepoint=='pre']='Pre-Treatment'
maf1520@clinical.data$Timepoint[maf1520@clinical.data$Timepoint=='pos']='Post-Treatment'
maf1520@clinical.data$Timepoint[c(23,29,42,47,37,39,44,45,49,50)] = 'Pre-Treatment'
maf1520@clinical.data$Timepoint[c(15,21,24,31)] = 'Post-Treatment'


maf1520@clinical.data$Patient = substr(maf1520@clinical.data$Tumor_Sample_Barcode,1,3)
#non-pCR Post-treatment
maf1520@clinical.data = maf1520@clinical.data[!(maf1520@clinical.data$Timepoint=='Post-Treatment' &
                                                  maf1520@clinical.data$Patient %in% 
                                                  complete_response$Patient[complete_response$complete_response=='Yes'])]

maf1520@clinical.data$matched = maf1520@clinical.data$Patient %in% maf1520@clinical.data$Patient[duplicated(maf1520@clinical.data$Patient)]
#Reorder the clinical data by patient and timepoint
maf1520@clinical.data = maf1520@clinical.data[order(-maf1520@clinical.data$matched,maf1520@clinical.data$Patient,-maf1520@clinical.data$Timepoint)]

#Colors for Oncoplot
PatientColors = c(rep(c(rep('gray',2),rep('white',2)),8),
                  rep(c('gray','white'),(nrow(maf1520@clinical.data)-32)/2),'gray')
names(PatientColors) = maf1520@clinical.data$Patient

TimepointColors= c('darkgreen','maroon')
names(TimepointColors) = c('Pre-Treatment','Post-Treatment')

anno_cols = list(Patient = PatientColors,Timepoint=TimepointColors)

clinical$complete_response[clinical$Patient %in% maf1520@clinical.data$Patient]

#Figure 2B: Oncoplot of matched pre and post
oncoplot(maf = maf1520,
         genes = genelist,
         clinicalFeatures=c('Timepoint','Patient'),
         annotationColor = anno_cols,
         draw_titv = FALSE,
         sampleOrder = maf1520@clinical.data$Tumor_Sample_Barcode,
         removeNonMutated = FALSE,
)

#Figure 2C: Changes in mutations by gene

oncoplot_changes = read.csv('oncoplot_changes.csv')
oncoplot_changes$Count = 1

oncoplot_changes$Mutation = factor(oncoplot_changes$Mutation,
                                   levels = c('TP53','KDM6A','ERBB3',
                                              'TSC1','STAG2','CDKN2A',
                                              'NOTCH1','FGFR3','TBL1XR1',
                                              'ETV6'))

ggplot(data = oncoplot_changes, aes(x = Change, y=Count, fill = Type)) + 
  geom_bar(stat='identity',position='stack')+xlab('')+ylab('Count')+theme_bw()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  facet_grid(~ Mutation)+ theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))+
  scale_y_continuous(breaks = seq(0, 10, by=2))+
  theme(axis.title=element_text(face="bold"))+
  scale_fill_manual(values=c('darkviolet','darkgreen',
                             'black','red','chocolate','darkgray'),name='')


#Figure 2D: Changes in mutations by patient

pm = read.csv('paired_mutations.csv')
pm$Patient=factor(pm$Patient,levels=c(1:16))
pm$Timepoint=factor(pm$Timepoint,levels=c('Pre','Post'))
pm$Gene=factor(pm$Gene,levels=c('TP53','KDM6A','ERBB3','TSC1','STAG2','CDKN2A','NOTCH1','FGFR3'))
ggplot(pm,aes(Timepoint,Gene,fill=Type))+geom_tile(color='gray',linewidth=0.3)+facet_grid(~Patient)+
  theme_bw()+theme(panel.grid = element_blank())+scale_fill_manual(values=c('darkviolet','darkgreen','black','red','chocolate'),name='')+ theme(strip.background = element_blank(),
                                                                                                                                                strip.text = element_blank())+
  xlab('Timepoint by Patient')+theme(axis.title=element_text(face='bold'))+theme(axis.text.x=element_text(angle=90,vjust=0.4))



#Figure 2E-G: Molecular subtypes

subtypes = read.delim('LCCC1520_subtype.txt',header=T)

#Define patient and timepoint
subtypes$Patient=substr(subtypes$ID,1,3)
subtypes$timepoint=substr(subtypes$ID,5,7)
subtypes$timepoint[subtypes$timepoint=='RE_'] = 'pos'
#remove old samples with poor QC that have been re-sequenced
subtypes = subtypes[-c(17,33),]

#Subset pre-and post-treatment subtypes
subtypes_pre = subtypes[subtypes$timepoint=='pre',]
subtypes_post = subtypes[subtypes$timepoint=='pos',]

#Select only post-treatment subtypes from non-pCR patients
subtypes_post = subtypes_post[subtypes_post$Patient %in% as.character(clinical$ID[clinical$complete_response=='No']),]

#Recombine pre-and post-treatment subtypes
subtypes_pre_post = full_join(subtypes_pre,subtypes_post,by='Patient')
colnames(subtypes_pre_post)[1:6] = c('ID','UNC.subtype','Lund.subtype','MDA.subtype','TCGA.subtype','Consensus')

#Select only subtype columns
subtypes_pre_post = subtypes_pre_post[,-c(7:12,14,16:17)]
colnames(subtypes_pre_post)[7] = 'MDA.post'
colnames(subtypes_pre_post)[8] = 'Consensus.post'

#Aesthetic changes to subtype names
subtypes_pre_post$Lund.subtype = as.factor(subtypes_pre_post$Lund.subtype)
subtypes_pre_post$MDA.subtype[subtypes_pre_post$MDA.subtype=='basal']= 'Basal'
subtypes_pre_post$MDA.subtype[subtypes_pre_post$MDA.subtype=='luminal']= 'Luminal'
subtypes_pre_post$MDA.post[subtypes_pre_post$MDA.post=='basal']= 'Basal'
subtypes_pre_post$MDA.post[subtypes_pre_post$MDA.post=='luminal']= 'Luminal'
subtypes_pre_post$TCGA.subtype[subtypes_pre_post$TCGA.subtype=='Basal_squamous']= 'Basal-squamous'
subtypes_pre_post$TCGA.subtype[subtypes_pre_post$TCGA.subtype=='Luminal_infiltrated']= 'Luminal-infiltrated'
subtypes_pre_post$TCGA.subtype[subtypes_pre_post$TCGA.subtype=='Luminal_papillary']= 'Luminal-papillary'

#Convert subtypes to factor format
subtypes_pre_post$UNC.subtype = factor(subtypes_pre_post$UNC.subtype,levels=c('Basal','Luminal'))
subtypes_pre_post$MDA.subtype = factor(subtypes_pre_post$MDA.subtype,levels=c('Basal','p53-like','Luminal'))
subtypes_pre_post$TCGA.subtype = factor(subtypes_pre_post$TCGA.subtype,levels=c('Basal-squamous','Luminal-infiltrated','Luminal-papillary','Luminal'))
subtypes_pre_post$Lund.subtype = factor(subtypes_pre_post$Lund.subtype,levels=c('UroA-Prog','UroC','Uro-Inf','UroB','GU','GU-Inf','Ba/Sq-Inf','Ba/Sq','Mes-like'))
subtypes_pre_post$Consensus = factor(subtypes_pre_post$Consensus,levels=c('Ba/Sq','Stroma-rich','LumU','LumP'))
subtypes_pre_post$Consensus.post = factor(subtypes_pre_post$Consensus.post,levels=c('Ba/Sq','Stroma-rich','LumU','LumP'))
subtypes_pre_post$MDA.post = factor(subtypes_pre_post$MDA.post,levels=c('Basal','p53-like','Luminal'))

#Figure 2E: All subtypes at pre-treatment
SankeyDiagram(subtypes_pre_post[, c(3,2,4,5,6)],
              link.color = "Source",
              label.show.varname = FALSE,
              font.size=14,
              max.categories=9,
              colors = c('lightgreen','yellow','cyan4','brown','steelblue','darkorchid4','red','coral2','orange',
                         'firebrick2','forestgreen',
                         'brown2','blueviolet','chartreuse3',
                         'firebrick3','green4','gold','dodgerblue',
                         "#FF1D1E","#D2FF1F","#237BFE","#20FF78"),
              weights = subtypes$freq,
              node.position.automatic = TRUE)




#Figure 2F: Consensus subtype, pre vs. post
consensus = subtypes_pre_post[,c(1,6,8)]
consensus$Consensus.post=as.character(consensus$Consensus.post)
consensus$Consensus.post[substr(consensus$ID,1,3) %in% as.character(clin$ID[clin$complete_response=='Yes'])]='pCR'
consensus = na.omit(consensus[,-1])
consensus$Consensus.post=factor(consensus$Consensus.post,levels=c('Stroma-rich','Ba/Sq','pCR','LumU','LumP'))
consensus$Consensus=factor(consensus$Consensus,levels=c('Ba/Sq','Stroma-rich','LumU','LumP'))
consensus

SankeyDiagram(consensus,
              link.color = "Source",
              label.show.varname = FALSE,
              font.size=14,
              max.categories=9,
              colors = c(
                "#FF1D1E","#D2FF1F","#237BFE","#20FF78",
                "#D2FF1F","#FF1D1E",'gray',"#237BFE","#20FF78"),
              weights = subtypes$freq,
              node.position.automatic = TRUE)



#Figure 2G: MDA subtype, pre vs. post
MDA = subtypes_pre_post[,c(1,4,7)]
MDA$MDA.post=as.character(MDA$MDA.post)
MDA$MDA.post[substr(MDA$ID,1,3) %in% as.character(clin$ID[clin$complete_response=='Yes'])]='pCR'
MDA = na.omit(MDA[,-1])
MDA$MDA.post=factor(MDA$MDA.post,levels=c('Luminal','p53-like','pCR'))
MDA$MDA.subtype=factor(MDA$MDA.subtype,levels=c('Basal','p53-like','Luminal'))


SankeyDiagram(MDA,
              link.color = "Source",
              label.show.varname = FALSE,
              font.size=14,
              max.categories=9,
              colors = c(
                'brown2','blueviolet','chartreuse3',
                'chartreuse3','blueviolet','gray'),
              weights = subtypes$freq,
              node.position.automatic = TRUE)

#Figure 2H: Immune gene signatures, pre vs. post

#Read in data
igs = read.delim('LCCC1520_immune_score.txt',header=T,sep='\t')
#Define patient and timepoint
igs$Patient = substr(igs$X,1,3)
igs$timepoint = substr(igs$X,nchar(igs$X)-3,nchar(igs$X)-3)
igs$timepoint[igs$timepoint == 'r'] = 'pre'
igs$timepoint[igs$timepoint == 's'] = 'post'

#remove old samples with poor QC that have been re-sequenced
igs = igs[-c(17,33),]

#Select only non-pCR tumors
igs = igs[igs$Patient %in% as.character(clinical$ID[clinical$complete_response=='No']),]

#Subset data by timepoint
sigs_pre = igs[igs$timepoint=='pre',]
sigs_post = igs[igs$timepoint=='post',]

#Select only matched patient data
sigs_pre = sigs_pre[sigs_pre$Patient %in% sigs_post$Patient,]
sigs_post = sigs_post[sigs_post$Patient %in% sigs_pre$Patient,]
sigs_pre = sigs_pre[sigs_pre$Patient %in% sigs_post$Patient,]


#Set up data frame for assessing differences between pre and post
sigs_df = data.frame(matrix(nrow=61,ncol=3))
colnames(sigs_df) = c('igs','diff','p')
sigs_df$igs = colnames(sigs_pre)[2:62]

#Aesthetic edits to signature names
sigs_df$igs[58] = 'IPRES_Responder'
sigs_df$igs[5] = 'IPRES_NonResponder'

#Compare absolute differences between pre and post
for (i in c(1:29,31:61)){
  a = sigs_pre[,(i+1)]
  b = sigs_post[,(i+1)]
  sigs_df[i,2] = mean(b-a)
  sigs_df[i,3] = wilcox.test(a,b,paired=TRUE)$p.value
}

#Remove Bindea_pDC, which is an incomplete signature
sigs_df = na.omit(sigs_df)

#Color and label by significance of differences
sigs_df$padj = p.adjust(sigs_df$p,method='BH')
sigs_df$col = 1*(sigs_df$padj<0.05) + 2*(sigs_df$diff>0)
sigs_df$col[sigs_df$col==0] = 'gray'
sigs_df$col[sigs_df$col==1] = 'darkblue'
sigs_df$col[sigs_df$col==2] = 'gray'
sigs_df$col[sigs_df$col==3] = 'darkred'
sigs_df$name = 1*(sigs_df$padj<0.05) + 2*(sigs_df$diff>0)
sigs_df$name[sigs_df$name==0] = 'NS'
sigs_df$name[sigs_df$name==1] = 'Down, sig.'
sigs_df$name[sigs_df$name==2] = 'NS'
sigs_df$name[sigs_df$name==3] = 'Up, sig.'
sigs_df$igs_short = sigs_df$igs
sigs_df$igs_short[sigs_df$padj>0.05] = ''

ggplot(sigs_df,aes(y = -log10(p),x=diff,col=col))+geom_point(size=4,alpha=0.6)+
  scale_colour_identity("",labels=sigs_df$name,breaks=sigs_df$col,guide="legend")+
  ylab('-Log10 paired Wilcoxon p-value')+xlab('Absolute increase, pre-to post-treatment')+
  geom_text_repel(aes(label=igs_short),show.legend=FALSE,size=4,col='black')+
  theme_bw()+ggtitle('Immune gene signatures,\nnon-pCR patients')+theme(plot.title = element_text(face="bold"),
                                                                        axis.title.y = element_text(face="bold"),
                                                                        axis.title.x = element_text(face="bold"),
                                                                        panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
                                                                        panel.background = element_blank(), axis.line = element_line(colour = "black"))






#Figure 2I: Tumor BCR/TCR diversity metrics

#Read in data
receptor = read.csv('receptor.csv')
receptor_id = read.csv('receptor_id.csv')

#Only analyze entropy and abundance
colnames(receptor)
receptor = receptor[,c(1,2,6,7,11,12,16,17,21,22,26)]

#Select only metrics from tumor samples
receptor_id = receptor_id[substr(receptor_id$Filename,1,4)=='1520',]

#Define patient and sample
receptor_id$Patient = substr(receptor_id$Filename,6,8)
colnames(receptor_id)[1] = 'Sample'

#Combine receptor and receptor_id
ri = full_join(receptor,receptor_id,by="Sample")

#Select only non-pCR tumors
ri = ri[ri$Patient %in% as.character(clinical$ID[clinical$complete_response=='No']),]

#Select pre-and post-treatment metrics
receptor_pre = ri[ri$Timepoint=='pre',]
receptor_post = ri[ri$Timepoint=='post',]

#Select only matched-pair samples
receptor_pre = receptor_pre[receptor_pre$Patient %in% receptor_post$Patient,]
receptor_post = receptor_post[receptor_post$Patient %in% receptor_pre$Patient,]
receptor_pre = receptor_pre[!duplicated(receptor_pre$Patient),]
receptor_post = receptor_post[!duplicated(receptor_post$Patient),]
colnames(receptor_pre)
#Set up data frame for assessing differences between pre and post
receptor_df = data.frame(matrix(nrow=10,ncol=3))
colnames(receptor_df) = c('pop','diff','p')
receptor_df$pop = colnames(receptor_pre)[2:11]

for (i in 1:10){
  a = na.omit(receptor_pre[,i+1])
  b = na.omit(receptor_post[,i+1])
  receptor_df$diff[i] = mean(b-a)/mean(a)*100
  receptor_df$p[i] = wilcox.test(a,b,paired=TRUE)$p.value
}
receptor_df$padj = p.adjust(receptor_df$p,method="BH")




receptor_df$col = 1*(receptor_df$padj<0.05) + 2*(receptor_df$diff>0)
receptor_df$col[receptor_df$col==0] = 'gray'
receptor_df$col[receptor_df$col==1] = 'darkblue'
receptor_df$col[receptor_df$col==2] = 'gray'
receptor_df$col[receptor_df$col==3] = 'darkred'
receptor_df$name = 1*(receptor_df$padj<0.05) + 2*(receptor_df$diff>0)
receptor_df$name[receptor_df$name==0] = 'NS'
receptor_df$name[receptor_df$name==1] = 'Down, sig.'
receptor_df$name[receptor_df$name==2] = 'NS'
receptor_df$name[receptor_df$name==3] = 'Up, sig.'
receptor_df$igs_short = receptor_df$pop
receptor_df$igs_short[receptor_df$padj>0.05] = ''


ggplot(receptor_df,aes(y = -log10(p),x=diff,col=col))+geom_point(size=4,alpha=0.6)+
  scale_colour_identity("",labels=receptor_df$name,breaks=receptor_df$col,guide="legend")+
  ylab('-Log10 paired Wilcoxon p-value')+xlab('% increase pre-to post-treatment')+
  geom_text_repel(aes(label=igs_short),show.legend=FALSE,size=4,col='black')+
  theme_bw()+ggtitle('Intratumor BCR and TCR Diversity,\nnon-pCR patients')+theme(plot.title = element_text(face="bold"),
                                                                                  axis.title.y = element_text(face="bold"),
                                                                                  axis.title.x = element_text(face="bold"),
                                                                                  panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
                                                                                  panel.background = element_blank(), axis.line = element_line(colour = "black"))



```


#Figure 3

```{r}

#Figure 3A: Peripheral blood immune populations

#Read in data
clinical = read.csv('Clinical1520.csv')
B = read.csv('LCCC1520_B_cells.csv')
Myeloid = read.csv('LCCC1520_Myeloid_cells.csv')
Teff = read.csv('LCCC1520_Teff-reg.csv')

#Rename first column as "ID"
colnames(B)[1] = 'ID'
colnames(Myeloid)[1] = 'ID'
colnames(Teff)[1] = 'ID'

#Define Patient
B$Patient = substr(B$ID,1,3)
Myeloid$Patient = substr(Myeloid$ID,2,4)
Teff$Patient = substr(Teff$ID,1,3)

#Define Timepoint
B$Timepoint = substr(B$ID,5,8)
Myeloid$Timepoint = substr(Myeloid$ID,6,9)
Teff$Timepoint = substr(Teff$ID,5,8)

#Rename "cystectomy" timepoint as "post"
B$Timepoint[substr(B$Timepoint,1,4)=='Cyst'] = 'Post'
Myeloid$Timepoint[substr(Myeloid$Timepoint,1,4)=='Cyst'] = 'Post'
Teff$Timepoint[substr(Teff$Timepoint,1,4)=='Cyst'] = 'Post'

#Combined Patient-Timepoint identifier
B$comb = paste(B$Patient,B$Timepoint)
Myeloid$comb = paste(Myeloid$Patient,Myeloid$Timepoint)
Teff$comb = paste(Teff$Patient,Teff$Timepoint)

#Only select rows with a Patient-Timepoint identifier
B = B[!is.na(B$comb),]
Myeloid = Myeloid[!is.na(Myeloid$comb),]
Teff = Teff[!is.na(Teff$comb),]

#Combine flow data
flow = full_join(B,Myeloid,by="comb")
flow = full_join(flow,Teff,by="comb")
flow$Patient = substr(flow$comb,1,3)

#Remove redundant ID columns
flow = flow[,c(2:19,24:29,33:63,22,64,65)]

#Convert percentages to integers
for (j in 1:55){
  for (i in 1:nrow(flow)){
    flow[i,j] = as.numeric(substr(flow[i,j],1,nchar(flow[i,j])-1))
  }
}

#Convert to numeric
for (j in 1:55){
  flow[,j] = as.numeric(flow[,j])
}

#Define Patient in clinical data
clinical$Patient = as.character(clinical$ID)

#Combine clinical and flow data, remove extra flow point (C2D8 in one patient)
flow_clin = full_join(flow,clinical,by='Patient')
flow_clin$Timepoint = substr(flow_clin$comb,5,8)
flow_clin = flow_clin[flow_clin$Timepoint!='C2D8',]

#Select Pre-Treatment (C1D1) data
fcpre = flow_clin[flow_clin$Timepoint == 'C1D1' & !is.na(flow_clin$Timepoint),]

#Select C2D1 data
fcc2 = flow_clin[flow_clin$Timepoint == 'C2D1' & !is.na(flow_clin$Timepoint),]




#Figure 3A: percent change from pre-treatment to C2D1

pre_c2_change = data.frame(matrix(nrow=55,ncol=5))
colnames(pre_c2_change) = c('pop','pre','c2','diff','p')
pre_c2_change$pop = colnames(fcc2)[c(1:55)]
prec2 = full_join(fcc2,fcpre,by="Patient")

for (j in c(1:55)){
  pre3  = prec2[!is.na(prec2[,j]) & !is.na(prec2[,j+ncol(fcc2)]),]
  df = data.frame(as.numeric(pre3[,j]),as.numeric(pre3[,j+ncol(fcc2)]))
  colnames(df) = c('c2','pre')
  pre_c2_change$pre[j] = mean(df$pre)
  pre_c2_change$c2[j] = mean(df$c2)
  pre_c2_change$diff[j] = mean(df$c2-df$pre)/mean(df$pre)*100
  pre_c2_change$p[j] = wilcox.test(df$pre,df$c2,paired=T)$p.value
}

pre_c2_change$padj = (p.adjust(pre_c2_change$p,method='BH'))
pre_c2_change$col = 1*(pre_c2_change$padj<0.05) + 2*(pre_c2_change$diff>0)
pre_c2_change$col[pre_c2_change$col==0] = 'gray'
pre_c2_change$col[pre_c2_change$col==1] = 'darkblue'
pre_c2_change$col[pre_c2_change$col==2] = 'gray'
pre_c2_change$col[pre_c2_change$col==3] = 'darkred'
pre_c2_change$name = 1*(pre_c2_change$padj<0.05) + 2*(pre_c2_change$diff>0)
pre_c2_change$name[pre_c2_change$name==0] = 'NS'
pre_c2_change$name[pre_c2_change$name==1] = 'Down, sig.'
pre_c2_change$name[pre_c2_change$name==2] = 'NS'
pre_c2_change$name[pre_c2_change$name==3] = 'Up, sig.'

pre_c2_change$igs_short = pre_c2_change$pop
pre_c2_change$igs_short[pre_c2_change$padj>0.05] = ''

pre_c2_change$igs_short[4] = 'CD19+ CD10+ Transitional B cells'
pre_c2_change$igs_short[19] = 'PMN_MDSC: CD14- CD15+ CD11b+'
pre_c2_change$igs_short[23] = 'eMDSC: Lin- HLADR- CD33+ CD11b+'
pre_c2_change$igs_short[28] = 'CD45RA+ CD4+ PD1+'
pre_c2_change$igs_short[32] = 'CD45RA+ CD8+ PD1+'
pre_c2_change$igs_short[39] = 'CD45RA- CD8+ PD1+'
pre_c2_change$igs_short[41] = 'CD45RA- CD4+ PD1+'
pre_c2_change$igs_short[42] = 'CD45RA- CD8+ CD39+'
pre_c2_change$igs_short[46] = 'CD45RA+ CD4+ Helios+'
pre_c2_change$igs_short[50] = 'CD45RA- CD4+ TIGIT+ CD39+'


ggplot(pre_c2_change,aes(y = -log10(p),x=diff,col=col))+geom_point(size=4,alpha=0.6)+
  scale_colour_identity("",labels=pre_c2_change$name,breaks=pre_c2_change$col,guide="legend")+
  ylab('-Log10 paired Wilcoxon p-value')+xlab('% increase, pre-treatment to C2')+
  geom_text_repel(aes(label=igs_short),col='black',show.legend=FALSE,size=3)+
  theme_bw()+ggtitle('Peripheal blood immune populations,\nall patients')+theme(plot.title = element_text(face="bold"),
                                                                                axis.title.y = element_text(face="bold"),
                                                                                axis.title.x = element_text(face="bold"),
                                                                                panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
                                                                                panel.background = element_blank(), axis.line = element_line(colour = "black"))




#Figure 3B-G: Plasma analytes

#Read in data
plasma = read.csv('1520plasma.csv',header=T)

#Convert mean calculated concentration to numeric
plasma$`Calc..Conc..Mean` = as.numeric(plasma$`Calc..Conc..Mean`)

#Relabel timepoints and patient IDs
plasma$Timepoint = sub("^\\S+\\s+", '', plasma$Sample)
plasma$Patient = gsub( " .*$", "", plasma$Sample)
plasma = plasma[plasma$Sample!='105/140 scrn',]
plasma$Patient[plasma$Patient=='105/140'|plasma$Patient=='140/141']= '140'
plasma$Timepoint[plasma$Timepoint == 'scrn'] = 'pre tx'
plasma$Timepoint[plasma$Timepoint == 'C1D1'] = 'pre tx'
plasma$Timepoint[plasma$Timepoint == 'C1D1 pre tx'] = 'pre tx'
plasma$Timepoint[plasma$Timepoint == 'C2D1'] = 'C2'
plasma$Timepoint[plasma$Timepoint == 'C2D8'] = 'C2'
plasma$Timepoint[plasma$Timepoint == 'surgical'] = 'post tx'
plasma$Timepoint[plasma$Timepoint == 'Cyst'] = 'post tx'
plasma$Timepoint[plasma$Timepoint == 'CYST'] = 'post tx'
plasma$Timepoint[plasma$Timepoint == 'Post Tx'] = 'post tx'
plasma$Timepoint = factor(plasma$Timepoint, levels = 
                            c('pre tx','C2','post tx'))

#Select only one of two reads (because we will use the mean concentration of the two)
plasma = plasma[c(1:3080)*2,]

#Join plasma with clinical
plasma_clin = left_join(plasma,clinical,by='Patient')

#Combine patient and analyte
plasma_clin$comb = paste(plasma_clin$Patient,plasma_clin$`Assay..Analyte.`)



#Figure 3B: Plasma pre-to post-treatment

#Subset data, pre-treatment (C1) and post-treatment
plasma_lfc_pre = plasma_clin[plasma_clin$Timepoint == 'pre tx',]
plasma_lfc_post = plasma_clin[plasma_clin$Timepoint == 'post tx',]
plasma_lfc_pre = plasma_lfc_pre[!is.na(plasma_lfc_pre$Calc..Conc..Mean),]
plasma_lfc_post = plasma_lfc_post[!is.na(plasma_lfc_post$Calc..Conc..Mean),]

#Recombine data
plasma_lfc = full_join(plasma_lfc_pre,plasma_lfc_post,by="comb")

#Only data from patients with complete response data
plasma_lfc = plasma_lfc[!is.na(plasma_lfc$complete_response.x) & !is.na(plasma_lfc$complete_response.y),]

#Names of analytes
analytes = na.omit(unique(plasma_lfc$`Assay..Analyte..x`))

#Changes in analytes
plasma_pre_c2_df = data.frame(matrix(nrow = length(analytes),ncol=3))
colnames(plasma_pre_c2_df) = c('analytes','p','coeff')
plasma_pre_c2_df$analytes = analytes

for (i in 1:nrow(plasma_pre_c2_df)){
  analyte = plasma_pre_c2_df$analytes[i]
  plasma_lfc2 = subset(plasma_lfc,plasma_lfc$`Assay..Analyte..x`==analyte)
  colnames(plasma_lfc2)
  plasma_lfc2 = na.omit(plasma_lfc2[,c(4,30)])
  plasma_pre_c2_df$p[i] = wilcox.test(plasma_lfc2$`Calc..Conc..Mean.x`,plasma_lfc2$`Calc..Conc..Mean.y`,paired=TRUE)$p.value
  plasma_pre_c2_df$coeff[i] = log2(mean(plasma_lfc2$`Calc..Conc..Mean.y`/plasma_lfc2$`Calc..Conc..Mean.x`))
}

plasma_pre_c2_df$padj = p.adjust(plasma_pre_c2_df$p,method='BH')
plasma_pre_c2_df$col = 1*(plasma_pre_c2_df$padj<0.05) + 2*(plasma_pre_c2_df$coeff>0)
plasma_pre_c2_df$col[plasma_pre_c2_df$col==0] = 'gray'
plasma_pre_c2_df$col[plasma_pre_c2_df$col==1] = 'darkblue'
plasma_pre_c2_df$col[plasma_pre_c2_df$col==2] = 'gray'
plasma_pre_c2_df$col[plasma_pre_c2_df$col==3] = 'darkred'
plasma_pre_c2_df$name = 1*(plasma_pre_c2_df$padj<0.05) + 2*(plasma_pre_c2_df$coeff>0)
plasma_pre_c2_df$name[plasma_pre_c2_df$name==0] = 'NS'
plasma_pre_c2_df$name[plasma_pre_c2_df$name==1] = 'Down, sig.'
plasma_pre_c2_df$name[plasma_pre_c2_df$name==2] = 'NS'
plasma_pre_c2_df$name[plasma_pre_c2_df$name==3] = 'Up, sig.'

plasma_pre_c2_df$igs_short = plasma_pre_c2_df$analyte
plasma_pre_c2_df$igs_short[plasma_pre_c2_df$padj>0.05] = ''
plasma_pre_c2_df$igs_short[plasma_pre_c2_df$igs_short=='MIG'] = 'CXCL9 (MIG)'

ggplot(plasma_pre_c2_df,aes(y = -log10(p),x=coeff,col=col))+geom_point(size=4,alpha=0.6)+
  scale_colour_identity("",labels=plasma_pre_c2_df$name,breaks=plasma_pre_c2_df$col,guide="legend")+
  ylab('-Log10 paired Wilcoxon p-value')+xlab('Log2 fold change, pre-to post-treatment')+
  geom_text_repel(aes(label=igs_short),col='black',show.legend=FALSE)+
  theme_bw()+ggtitle('Plasma analyte concentrations, all patients')+theme(plot.title = element_text(face="bold"),
                                                                          axis.title.y = element_text(face="bold"),
                                                                          axis.title.x = element_text(face="bold"),
                                                                          panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
                                                                          panel.background = element_blank(), axis.line = element_line(colour = "black"))



#Figure 3C: Changes in analytes pre-treatment to C2

#Subset data, pre-treatment (C1) and C2
plasma_lfc_pre = plasma_clin[plasma_clin$Timepoint == 'pre tx',]
plasma_lfc_c2 = plasma_clin[plasma_clin$Timepoint == 'C2',]
plasma_lfc_pre = plasma_lfc_pre[!is.na(plasma_lfc_pre$Calc..Conc..Mean),]
plasma_lfc_c2 = plasma_lfc_c2[!is.na(plasma_lfc_c2$Calc..Conc..Mean),]

#Recombine data
plasma_lfc = full_join(plasma_lfc_pre,plasma_lfc_c2,by="comb")

#Only data from patients with complete response data
plasma_lfc = plasma_lfc[!is.na(plasma_lfc$complete_response.x) & !is.na(plasma_lfc$complete_response.y),]

#Names of analytes
analytes = na.omit(unique(plasma_lfc$`Assay..Analyte..x`))

#Changes in analytes
plasma_pre_c2_df = data.frame(matrix(nrow = length(analytes),ncol=3))
colnames(plasma_pre_c2_df) = c('analytes','p','coeff')
plasma_pre_c2_df$analytes = analytes

for (i in 1:nrow(plasma_pre_c2_df)){
  analyte = plasma_pre_c2_df$analytes[i]
  plasma_lfc2 = subset(plasma_lfc,plasma_lfc$`Assay..Analyte..x`==analyte)
  plasma_lfc2 = na.omit(plasma_lfc2[,c(4,30)])
  plasma_pre_c2_df$p[i] = wilcox.test(plasma_lfc2$`Calc..Conc..Mean.x`,plasma_lfc2$`Calc..Conc..Mean.y`,paired=TRUE)$p.value
  plasma_pre_c2_df$coeff[i] = log2(mean(plasma_lfc2$`Calc..Conc..Mean.y`/plasma_lfc2$`Calc..Conc..Mean.x`))
}

plasma_pre_c2_df$padj = p.adjust(plasma_pre_c2_df$p,method='BH')
plasma_pre_c2_df$col = 1*(plasma_pre_c2_df$padj<0.05) + 2*(plasma_pre_c2_df$coeff>0)
plasma_pre_c2_df$col[plasma_pre_c2_df$col==0] = 'gray'
plasma_pre_c2_df$col[plasma_pre_c2_df$col==1] = 'darkblue'
plasma_pre_c2_df$col[plasma_pre_c2_df$col==2] = 'gray'
plasma_pre_c2_df$col[plasma_pre_c2_df$col==3] = 'darkred'
plasma_pre_c2_df$name = 1*(plasma_pre_c2_df$padj<0.05) + 2*(plasma_pre_c2_df$coeff>0)
plasma_pre_c2_df$name[plasma_pre_c2_df$name==0] = 'NS'
plasma_pre_c2_df$name[plasma_pre_c2_df$name==1] = 'Down, sig.'
plasma_pre_c2_df$name[plasma_pre_c2_df$name==2] = 'NS'
plasma_pre_c2_df$name[plasma_pre_c2_df$name==3] = 'Up, sig.'

plasma_pre_c2_df$igs_short = plasma_pre_c2_df$analyte
plasma_pre_c2_df$igs_short[plasma_pre_c2_df$padj>0.05] = ''
plasma_pre_c2_df$igs_short[plasma_pre_c2_df$igs_short=='MIG'] = 'CXCL9 (MIG)'

ggplot(plasma_pre_c2_df,aes(y = -log10(p),x=coeff,col=col))+geom_point(size=4,alpha=0.6)+
  scale_colour_identity("",labels=plasma_pre_c2_df$name,breaks=plasma_pre_c2_df$col,guide="legend")+
  ylab('-Log10 paired Wilcoxon p-value')+xlab('Log2 fold change pre-treatment to C2')+
  geom_text_repel(aes(label=igs_short),col='black',show.legend=FALSE)+
  theme_bw()+ggtitle('Plasma analyte concentrations,\nall patients')+theme(plot.title = element_text(face="bold"),
                                                                           axis.title.y = element_text(face="bold"),
                                                                           axis.title.x = element_text(face="bold"),
                                                                           panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
                                                                           panel.background = element_blank(), axis.line = element_line(colour = "black"))



#Figure 3D: Change in analytes, pre-treatment to C2, #Responders vs. NR

#Combine data
plasma_lfc = full_join(plasma_lfc_pre,plasma_lfc_c2,by="comb")

#Only data from patients with complete response data
plasma_lfc = plasma_lfc[!is.na(plasma_lfc$complete_response.x) & !is.na(plasma_lfc$complete_response.y),]

#Names of analytes
analytes = na.omit(unique(plasma_lfc$`Assay..Analyte..x`))

#Changes in analytes
change_df = data.frame(matrix(nrow = length(analytes),ncol=4))
colnames(change_df) = c('analytes','lfc_resp','lfc_nr','p')
change_df$analytes = analytes

for (i in 1:nrow(change_df)){
  analyte = change_df$analytes[i]
  plasma_lfc2 = subset(plasma_lfc,plasma_lfc$`Assay..Analyte..x`==analyte)
  colnames(plasma_lfc2)
  plasma_lfc2 = na.omit(plasma_lfc2[,c(4,30,22)])
  resp = plasma_lfc2[plasma_lfc2$Pathologic_Responder.x=='Yes',]
  nr = plasma_lfc2[plasma_lfc2$Pathologic_Responder.x=='No',]
  change_df$lfc_resp[i] = mean(log2(resp$Calc..Conc..Mean.y/resp$Calc..Conc..Mean.x))
  change_df$lfc_nr[i] = mean(log2(nr$Calc..Conc..Mean.y/nr$Calc..Conc..Mean.x))
  change_df$p[i] = wilcox.test(log2(resp$Calc..Conc..Mean.y/resp$Calc..Conc..Mean.x),log2(nr$Calc..Conc..Mean.y/nr$Calc..Conc..Mean.x))$p.value
}

change_df$padj = p.adjust(change_df$p,method='BH')
change_df$col = 1*(change_df$padj<0.05)
change_df$col[change_df$col==0] = 'gray'
change_df$col[change_df$col==1] = 'darkred'
change_df$name = 1*(change_df$padj<0.05)
change_df$name[change_df$name==0] = 'NS'
change_df$name[change_df$name==1] = 'Up, sig.'

change_df$name_short = change_df$analyte
change_df$name_short[change_df$padj>0.05] = ''

ggplot(change_df,aes(y = lfc_resp,x=lfc_nr,col=col))+geom_point(size=4,alpha=0.6)+
  scale_colour_identity("",labels=c('More increase with\nresponse, sig.','NS'),guide="legend")+
  xlab('Log2 fold change in non-responders')+ylab('Log2 fold change in responders')+
  geom_text_repel(aes(label=name_short),col='black',show.legend=FALSE)+
  theme_bw()+ggtitle('Plasma analyte concentrations,\nall patients')+theme(plot.title = element_text(face="bold"),
                                                                           axis.title.y = element_text(face="bold"),
                                                                           axis.title.x = element_text(face="bold"),
                                                                           panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
                                                                           panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  geom_abline(slope=1,lty=2)





#Figure 3E: Change in IL-9, pre-treatment to C2

#Select only IL-9
il9_pre = plasma_lfc_pre[plasma_lfc_pre$Assay..Analyte.=='IL-9',]
il9_pre$Timepoint='Pre-Treatment'
il9_c2 = plasma_lfc_c2[plasma_lfc_c2$Assay..Analyte.=='IL-9',]
il9_c2$Timepoint='C2'

#Combine pre and c2
il9 = rbind(il9_pre,il9_c2)
il9 = il9[!is.na(il9$Pathologic_Responder),]
il9$Timepoint = factor(il9$Timepoint,levels=c('Pre-Treatment','C2'))
il9$Pathologic_Responder[il9$Pathologic_Responder=='No'] = 'No Response'
il9$Pathologic_Responder[il9$Pathologic_Responder=='Yes'] = 'Response'

#Remove non-paired values
il9 = il9[il9$Patient %in% il9$Patient[duplicated(il9$Patient)],]

ggplot(il9, aes(Timepoint, Calc..Conc..Mean))+
  geom_point(aes(color = Timepoint),size=4) +
  geom_line(aes(group = interaction(Patient, Pathologic_Responder)))+
  facet_grid(~Pathologic_Responder)+
  stat_compare_means(label = "p.format", paired = TRUE,label.y=180)+
  theme_bw()+ylab('IL-9 Concentration')+xlab('')+theme(legend.position='',
                                                       panel.grid.major = element_blank(),
                                                       panel.grid.minor = element_blank())+
  scale_color_manual(values=c('darkgreen','tan3'))+
  xlab('Timepoint')+
  theme(axis.title=element_text(face='bold'))



#Figure 3F: Change in IL-9 vs. response, ROC

il9 = full_join(il9_pre,il9_c2,by='Patient')
il9$change = (il9$Calc..Conc..Mean.y-il9$Calc..Conc..Mean.x)/il9$Calc..Conc..Mean.x*100

plot(roc(il9$Pathologic_Responder.x~il9$change),print.auc=T,
     main='Response predicted by\nchange in IL-9, pre-treatment to C2')



#Figure 3G: Change in IL-9 vs. response, GLM
il9 = il9[!is.na(il9$Pathologic_Responder.x),]

summary(glm(il9$Pathologic_Responder.x=='Yes'~il9$change,family=binomial(link="logit")))$coefficients

ggplot(il9,aes(y=1*(Pathologic_Responder.x=='Yes'), x=change))+
  geom_jitter(width=0,height=0.05,size=4,alpha=0.6,
              aes(color=Pathologic_Responder.x)) +
  geom_smooth(method = "glm", 
              method.args = list(family = "binomial"), 
              se = TRUE)+
  scale_color_manual(values=c('brown','orchid'),labels=c('Response','No Response'),name='')+
  theme_bw()+ggtitle('p = 0.015, Coefficient = 0.027, SE = 0.011')+ylab('')+
  xlab('% change in IL-9 concentration,\npre-treatment to C2')+
  theme(axis.text.y=element_blank(),axis.ticks.y=element_blank(),
        plot.title = element_text(face="bold"),
        axis.title.x = element_text(face="bold"),
        panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"))


```


#Figure 4

```{r}


#Figure 4A: Plot counts of all predicted antigens

#Read in data

post111 = read.delim('IMGF_1520-111_post.lens_report.txt')
pre111 = read.delim('IMGF_1520-111_pre.lens_report.txt')

post112 = read.delim('IMGF_1520-112_post.lens_report.txt')
pre112 = read.delim('IMGF_1520-112_pre.lens_report.txt')

pre113 = read.delim('IMGF_1520-113_pre.lens_report.txt')

pre114 = read.delim('IMGF_1520-114_pre.lens_report.txt')

post115 = read.delim('IMGF_1520-115_post.lens_report.txt')
pre115 = read.delim('IMGF_1520-115_pre.lens_report.txt')

post116 = read.delim('IMGF_1520-116_post.lens_report.txt')

post117 = read.delim('IMGF_1520-117_post.lens_report.txt')
pre117 = read.delim('IMGF_1520-117_pre.lens_report.txt')

pre119 = read.delim('IMGF_1520-119_pre.lens_report.txt')

post120 = read.delim('IMGF_1520-120_post.lens_report.txt')
pre120 = read.delim('IMGF_1520-120_pre.lens_report.txt')

post121 = read.delim('IMGF_1520-121_post.lens_report.txt')
pre121 = read.delim('IMGF_1520-121_pre.lens_report.txt')

post122 = read.delim('IMGF_1520-122_post.lens_report.txt')
pre122 = read.delim('IMGF_1520-122_pre.lens_report.txt')

post123 = read.delim('IMGF_1520-123_post.lens_report.txt')
pre123 = read.delim('IMGF_1520-123_pre.lens_report.txt')

post124 = read.delim('IMGF_1520-124_post.lens_report.txt')
pre124 = read.delim('IMGF_1520-124_pre.lens_report.txt')

pre125 = read.delim('IMGF_1520-125_pre.lens_report.txt')

pre126 = read.delim('IMGF_1520-126_pre.lens_report.txt')

pre127 = read.delim('IMGF_1520-127_pre.lens_report.txt')

pre128 = read.delim('IMGF_1520-128_pre.lens_report.txt')

pre130 = read.delim('IMGF_1520-130_pre.lens_report.txt')

post131 = read.delim('IMGF_1520-131_post.lens_report.txt')
pre131 = read.delim('IMGF_1520-131_pre.lens_report.txt')

pre133 = read.delim('IMGF_1520-133_pre.lens_report.txt')

pre134 = read.delim('IMGF_1520-134_pre.lens_report.txt')

pre136 = read.delim('IMGF_1520-136_pre.lens_report.txt')

pre137 = read.delim('IMGF_1520-137_pre.lens_report.txt')

pre138 = read.delim('IMGF_1520-138_pre.lens_report.txt')

pre139 = read.delim('IMGF_1520-139_pre.lens_report.txt')

post140 = read.delim('IMGF_1520-140_post.lens_report.txt')
pre140 = read.delim('IMGF_1520-140_pre.lens_report.txt')

post143 = read.delim('IMGF_1520-143_post.lens_report.txt')

post144 = read.delim('IMGF_1520-144_post.lens_report.txt')


#Combine into lists, pre and post

pre = list(pre111,pre112,pre113,pre114,pre115,pre117,pre119,pre120,
           pre121,pre122,pre123,pre124,pre125,pre126,pre127,pre128,
           pre130,pre131,pre133,pre134,pre136,pre137,pre138,
           pre139,pre140)

names_pre = as.vector(c('pre111','pre112','pre113','pre114','pre115','pre117','pre119','pre120',
                        'pre121','pre122','pre123','pre124','pre125','pre126','pre127',
                        'pre128',
                        'pre130','pre131','pre133','pre134','pre136','pre137','pre138',
                        'pre139','pre140'))

post = list(post111,post112,post115,post116,post117,post120,post121,post123,post124,post131,post140,
            post143,post144)


names_post = as.vector(c('post111','post112','post115','post116','post117',
                         'post120','post121','post123','post124','post131','post140',
                         'post143','post144'))


#Select non-duplicated antigens

for (i in 1:length(pre)){
  df= data.frame(pre[i])
  df$patient = names_pre[i]
  pre[i] = list(df[!duplicated(df$peptide),])
}


for (i in 1:length(post)){
  df= data.frame(post[i])
  df$patient = names_post[i]
  post[i] = list(df[!duplicated(df$peptide),])
}


#Reformat as data frames
antigens_pre = ldply(pre, data.frame)
antigens_post = ldply(post, data.frame)


#Select only antigens with lower than 500 BA and greater than 5 reads per peptide
antigens_pre = antigens_pre[antigens_pre$binding_affinity<500 & antigens_pre$reads_with_peptide>5,]
antigens_post = antigens_post[antigens_post$binding_affinity<500 & antigens_post$reads_with_peptide>5,]


#Make a table of antigen counts
tab = as.matrix(table(antigens_pre$patient,antigens_pre$antigen_source))
order_names = order(-rowSums(tab))


#Convert into a data frame
df = data.frame(table(antigens_pre$patient,antigens_pre$antigen_source))
df$Freq = as.numeric(df$Freq)
df$Var1 = factor(df$Var1,levels=unique(df$Var1)[order_names])

df$Antigen_Source = as.factor(df$Var2)

#Divide into self (CTA) and non-self antigens
df_self = df[df$Var2 == 'Self-Antigen',]
df_other = df[df$Var2 != 'Self-Antigen',]

df_other$Antigen_Source = factor(df_other$Antigen_Source,levels=c('InDel','SpliceVariant','SNV','ERV'))


ggplot(data = df_self, aes(x = Var1, y = Freq, fill = Antigen_Source)) + 
  geom_bar(stat='identity')+xlab('')+ylab('Count')+theme_bw()+
  theme(axis.text.x=element_blank(),axis.ticks.x=element_blank(),panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  scale_fill_manual(values=c('#87E911'),name='Antigen source')+ggtitle('Pre-treatment antigen counts')+
  theme(axis.title=element_text(face='bold'),title=element_text(face='bold'))

ggplot(data = df_other, aes(x = Var1, y = Freq, fill = Antigen_Source)) + 
  geom_bar(stat='identity')+xlab('')+ylab('Count')+theme_bw()+
  theme(axis.text.x=element_blank(),axis.ticks.x=element_blank(),panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  scale_fill_manual(values=c('#F2CA19','#0057E9',
                             '#FF00BD',
                             '#8931EF'),name='Antigen source')+
  theme(axis.title=element_text(face='bold'))



#TMB strip

#Read in TMB
setwd("/Users/wolf/Desktop/LCCC1520_Revised_DATA 2")
tmb = read.csv('LCCC1520_TMB.csv')

#Remove old, poor QC reads
tmb = tmb[-c(17,31),]

#Define patient and timepoint
tmb$Patient = substr(tmb$Sample_ID,1,3)
tmb$Timepoint = substr(tmb$Sample_ID,5,7)

#Only pre-treatment samples
tmb_pre = tmb[tmb$Timepoint=='pre',]

tmb2 = tmb_pre[tmb_pre$Patient %in% substr(df$Var1,4,6),]
tmb2$Patient = factor(tmb2$Patient,levels = c(tmb2$Patient[order_names]))

ggplot(data = tmb2, aes(x = Patient, y = TMB)) + 
  geom_bar(stat='identity')+xlab('')+ylab('TMB')+theme_bw()+
  theme(axis.text.x=element_blank(),axis.ticks.x=element_blank(),panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  scale_fill_manual(values='gray')



#IL-9
#Read in data

clinical = read.csv('Clinical1520.csv')
clinical$Patient = as.character(clinical$ID)
clin = clinical
plasma = read.csv('1520plasma.csv',header=T)

#Convert mean calculated concentration to numeric
plasma$`Calc..Conc..Mean` = as.numeric(plasma$`Calc..Conc..Mean`)

#Relabel timepoints and patient IDs
plasma$Timepoint = sub("^\\S+\\s+", '', plasma$Sample)
plasma$Patient = gsub( " .*$", "", plasma$Sample)
plasma = plasma[plasma$Sample!='105/140 scrn',]
plasma$Patient[plasma$Patient=='105/140'|plasma$Patient=='140/141']= '140'
plasma$Timepoint[plasma$Timepoint == 'scrn'] = 'pre tx'
plasma$Timepoint[plasma$Timepoint == 'C1D1'] = 'pre tx'
plasma$Timepoint[plasma$Timepoint == 'C1D1 pre tx'] = 'pre tx'
plasma$Timepoint[plasma$Timepoint == 'C2D1'] = 'C2'
plasma$Timepoint[plasma$Timepoint == 'C2D8'] = 'C2'
plasma$Timepoint[plasma$Timepoint == 'surgical'] = 'post tx'
plasma$Timepoint[plasma$Timepoint == 'Cyst'] = 'post tx'
plasma$Timepoint[plasma$Timepoint == 'CYST'] = 'post tx'
plasma$Timepoint[plasma$Timepoint == 'Post Tx'] = 'post tx'
plasma$Timepoint = factor(plasma$Timepoint, levels = 
                            c('pre tx','C2','post tx'))

#Select only one of two reads (because we will use the mean concentration of the two)
plasma = plasma[c(1:3080)*2,]

#Join plasma with clinical
plasma_clin = left_join(plasma,clinical,by='Patient')

il9 = plasma_clin[plasma_clin$Assay..Analyte.=='IL-9',]
il9 = il9[il9$Patient %in% tmb2$Patient & il9$Timepoint=='pre tx',]



#Ayers_IFNG and Bindea_CD8_T_cells

#Read in data
igs = read.delim('LCCC1520_immune_score.txt',header=T,sep='\t')
#Define patient and timepoint
igs$Patient = substr(igs$X,1,3)
igs$timepoint = substr(igs$X,nchar(igs$X)-3,nchar(igs$X)-3)
igs$timepoint[igs$timepoint == 'r'] = 'pre'
igs$timepoint[igs$timepoint == 's'] = 'post'

#remove old samples with poor QC that have been re-sequenced
igs = igs[-c(17,33),]

#select only pre-treatment IGS
igs_pre = igs[igs$timepoint=='pre',]
igs_pre = igs_pre[igs_pre$Patient %in% tmb2$Patient,]

#Join IGS and IL-9 data

igs_il9 = full_join(igs_pre,il9,by='Patient')

igs_il9$IL9 = igs_il9$Calc..Conc..Mean
igs_il9 = igs_il9[,colnames(igs_il9) %in% c('Ayers_IFNG', 'Bindea_CD8_T_cells','IL9')]
colnames(igs_il9)[colnames(igs_il9)=='IL9']='IL-9'
igs_il9 = data.frame(t(igs_il9))

#Convert to numeric format
for (i in 1:nrow(igs_il9)){
  igs_il9[i,] = as.numeric(scale(as.numeric(igs_il9[i,])))
}

igs_il9 = data.matrix(igs_il9)
igs_il9 = igs_il9[,order_names]

heatmap.2(igs_il9, scale = "none",col=bluered(100),
          trace = "none", density.info = "none",
          margins=c(10,10),
          dendrogram='none',cexCol=1,cexRow=1,
          Rowv=FALSE, Colv=FALSE,labCol=FALSE)


#Response strip
igs_il9 = full_join(igs_pre,il9,by='Patient')
igs_il9$Response = factor(1*(igs_il9$complete_response=='Yes')+1*(igs_il9$Pathologic_Responder=='Yes'))
igs_il9 = igs_il9[order_names,]
ggplot(igs_il9,aes(x=rownames(igs_il9),y=1,fill=igs_il9$Response))+geom_tile()+theme_bw()+
  scale_fill_manual(values=c('brown','yellow','orange'),name='',labels=c('NR','PR','CR'))+
  theme(axis.text = element_blank(),axis.ticks=element_blank())+ylab('')+xlab('')+
  theme(panel.grid=element_blank())





#Figure 4B: Shared self-antigens

self = antigens_pre[antigens_pre$antigen_source=='Self-Antigen',]

#Calculate number shared
crossprod = crossprod(table(self$peptide,self$patient))

#Adjust the number for color scale purposes while plotting
crossprod = ((crossprod/max(crossprod))*2)-1

ggcorrplot(crossprod, hc.order = TRUE, type = "lower", outline.col = "white",
           colors = c("black", "yellow"),
           show.diag= FALSE
)+theme_bw()+
  scale_fill_gradient(breaks=c(-1,-0.5, 0), labels=c(0,75,149),limit=c(-1, 0),low='black',high='yellow',
                      name='Number of Shared\nSelf-Antigens')+
  theme(
    axis.ticks.x=element_blank(),
    axis.ticks.y=element_blank(),
    axis.text.x=element_blank(),
    axis.text.y=element_blank(),
    panel.grid.major=element_blank()
  )+
  xlab('')+ylab('')+ggtitle('Self-Antigens in Pre-Treatment Tumors')+
  xlab('Tumor')+ylab('Tumor')+
  theme(axis.title=element_text(face='bold'),
        title=element_text(face='bold'))



#Figure 4C: Changes in antigen counts

antigens_pre = ldply(pre, data.frame)
antigens_post = ldply(post, data.frame)

#Define Patient
antigens_pre$Patient = substr(antigens_pre$patient,4,6)
antigens_post$Patient = substr(antigens_post$patient,5,7)

#Join with clinical data
antigens_pre_clin= full_join(antigens_pre,clin,by='Patient')
antigens_post_clin= full_join(antigens_post,clin,by='Patient')

#Select only patients with both pre and post data
antigens_pre_clin2 = antigens_pre_clin[antigens_pre_clin$Patient %in% antigens_post_clin$Patient,]
antigens_post_clin2 = antigens_post_clin[antigens_post_clin$Patient %in% antigens_pre_clin2$Patient,]

#Remove NA rows
antigens_pre_clin2 = antigens_pre_clin2[antigens_pre_clin2$Patient %in% antigens_pre$Patient  & !is.na(antigens_pre_clin2$Patient),]
antigens_post_clin2 = antigens_post_clin2[antigens_post_clin2$Patient %in% antigens_post$Patient & !is.na(antigens_post_clin2$Patient),]

#Select only patients with both pre and post data
antigens_pre_clin3 = antigens_pre_clin2[antigens_pre_clin2$Patient %in% antigens_post_clin2$Patient,]
antigens_post_clin3 = antigens_post_clin2[antigens_post_clin2$Patient %in% antigens_pre_clin2$Patient,]


#Select patients without pCR
antigens_pre_clin3 = antigens_pre_clin3[antigens_pre_clin3$complete_response!='Yes'
                                        ,]
antigens_post_clin3 = antigens_post_clin3[antigens_post_clin3$complete_response!='Yes'
                                          ,]

#Only antigens with BA < 500
antigens_post_clin3 = antigens_post_clin3[antigens_post_clin3$binding_affinity<500,]
antigens_pre_clin3 = antigens_pre_clin3[antigens_pre_clin3$binding_affinity<500,]

#Combine pre and post into one data frame
antigens_pre_post_clin = rbind(antigens_post_clin3,antigens_pre_clin3)
antigens_pre_post_clin2 = data.frame(antigens_pre_post_clin$peptide,antigens_pre_post_clin$reads_with_peptide)
colnames(antigens_pre_post_clin2) = c('peptide','reads_with_peptide')
antigens_pre_post_clin3 = aggregate(reads_with_peptide~peptide,antigens_pre_post_clin2,sum)
#Only antigens with reads > 5
antigens_pre_post_clin3 = antigens_pre_post_clin3[antigens_pre_post_clin3$reads_with_peptide>5,]

#Select only the antigens present in the combined list
antigens_post_clin3 = antigens_post_clin3[antigens_post_clin3$peptide %in% antigens_pre_post_clin3$peptide,]
antigens_pre_clin3 = antigens_pre_clin3[antigens_pre_clin3$peptide %in% antigens_pre_post_clin3$peptide,]

#Gained, lost, retained
antigens_pre_clin_lost = antigens_pre_clin3[!(antigens_pre_clin3$peptide %in% antigens_post_clin3$peptide),]
antigens_pre_clin_retained = antigens_pre_clin3[(antigens_pre_clin3$peptide %in% antigens_post_clin3$peptide),]
antigens_pre_clin_gained = antigens_post_clin3[!(antigens_post_clin3$peptide %in% antigens_pre_clin3$peptide),]

#Label the lists
antigens_pre_clin_lost$group = 'lost'
antigens_pre_clin_retained$group = 'retained'
antigens_pre_clin_gained$group = 'gained'

#Recombine the lists
antigens_pre_clin_all = rbind(antigens_pre_clin_lost,antigens_pre_clin_retained,antigens_pre_clin_gained)


#Make into a data frame of counts
antigen_counts_df = data.frame(antigens_pre_clin_all$patient,antigens_pre_clin_all$antigen_source,antigens_pre_clin_all$group)
antigen_counts_df = data.frame(table(antigen_counts_df))
antigen_counts_df = antigen_counts_df[antigen_counts_df$Freq!=0,]
antigen_counts_df = as.data.frame(antigen_counts_df)

colnames(antigen_counts_df) = c('patient','Antigen_Source','group','Freq')
antigen_counts_df$patient = substr(antigen_counts_df$patient,nchar(as.character(antigen_counts_df$patient))-2,nchar(as.character(antigen_counts_df$patient)))

#Label by response
names = c('112' = 'NR',
          '121' = 'NR',
          '123' = 'NR',
          '124' = 'NR',
          '126' = 'NR',
          '131' = 'NR',
          '137' = 'NR',
          '115' = 'PR',
          '117' = 'PR',
          '120' = 'PR',
          '127' = 'PR',
          '128' = 'PR',
          '139' = 'PR',
          '140' = 'PR'
)

antigen_counts_df$patient = factor(antigen_counts_df$patient, levels = c('112','121','123','124','131','115','117','120','140'))

strip = strip_themed(background_x = elem_list_rect(fill=c(rep('brown',5),rep('yellow',4))))

ggplot(data = antigen_counts_df, aes(x = group, y = Freq, fill = Antigen_Source)) + 
  geom_bar(stat='identity',position='stack')+xlab('')+ylab('Count')+theme_bw()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  facet_grid2(~ patient,strip=strip,labeller = as_labeller(names))+ theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))+
  scale_fill_manual(values=c('#8931EF','#87E911',
                             '#FF00BD','#0057E9'))




#Figures 4D-F: Wells criteria

#Select Wells criteria antigens
antigens_pre_clin8 = antigens_pre_clin[antigens_pre_clin$tpm>33 & antigens_pre_clin$binding_affinity<34 & antigens_pre_clin$binding_stability>1.4,]
wells_df = data.matrix(table(antigens_pre_clin8$patient,antigens_pre_clin8$antigen_source))
wells_df = wells_df[rowSums(wells_df)!=0,]
wells_df = as.data.frame(wells_df)

wells_df2 = data.matrix(table(antigens_pre_clin$patient,antigens_pre_clin$antigen_source))
table(antigens_pre_clin$patient,antigens_pre_clin$Pathologic_Responder)
wells_df2 = as.data.frame(wells_df2)
wells_df2$Freq=0

#Fix label for patient 121
wells_df2$Var1 = '121'

#Combine data frames
wells_df = rbind(wells_df2,wells_df)

#Format data frame for plotting
wells_df$Var1 = as.factor(wells_df$Var1)
wells_df$Antigen_Source = factor(wells_df$Var2,levels=unique(antigens_pre_clin$antigen_source))
wells_df$Var1 = factor(wells_df$Var1, levels=c(unique(antigens_pre_clin8$patient[order(antigens_pre_clin8$patient)])[order(-table(antigens_pre_clin8$patient))]))
wells_df$Antigen_Source = factor(wells_df$Antigen_Source,levels=c('ERV','FusionEvent','InDel','Self-Antigen','SNV','SpliceVariant'))
wells_df = wells_df[wells_df$Freq!=0,]

#Remove NA values
antigens_pre_clin8 = antigens_pre_clin8[!is.na(antigens_pre_clin8$antigen_source),]

#Figure 4D: counts

#Figure 4D: counts
ggplot(data = wells_df, aes(x = Var1, y = Freq, fill = Antigen_Source)) + 
  geom_bar(stat='identity',position='stack')+xlab('')+ylab('Count')+theme_bw()+
  theme(
    axis.text.x=element_blank(),
    panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
    axis.ticks.x=element_blank())+
  xlab('Patients with >1 antigen by Wells criteria')+
  scale_fill_manual(values=c('#8931EF','#87E911',
                             '#FF00BD'),name='Antigen source')+ggtitle('Antigens filtered by Wells criteria (expression>33TPM,\nbinding affinity<34nM, binding stability>1.4s)')+
  theme(axis.title=element_text(face='bold'),title=element_text(face='bold'))


#Figure 4E: BA vs. BS

ggplot(antigens_pre_clin8,aes(binding_affinity,binding_stability,col=antigen_source))+
  geom_point(alpha=0.6,size=5)+
  scale_color_manual(values=c('#8931EF','#87E911',
                              '#FF00BD'),name='Atigen source')+
  ggtitle('Antigens filtered by Wells criteria')+theme_bw()+
  xlab('Binding affinity (nM)')+ylab('Binding stability (s)')+labs(color='Antigen Source')+
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        axis.title=element_text(face='bold'),
        title=element_text(face='bold'))


#Figure 4F: TPM by antigen source

ggplot(antigens_pre_clin8,aes(y=tpm,x=antigen_source,
                              fill=antigen_source,col=antigen_source))+
  geom_boxplot(outlier.shape=NA,alpha=0.2)+
  geom_jitter(width=0.2,size=4,alpha=0.6,aes(fill=antigen_source))+
  scale_fill_manual(values=c('#8931EF','#87E911','#FF00BD'))+
  scale_color_manual(values=c('#8931EF','#87E911','#FF00BD'))+
  theme_bw()+
  xlab('')+ylab('TPM')+labs(color='Antigen Source')+
  scale_y_continuous(trans='log10')+theme(legend.position = '')+
  stat_compare_means(comparisons=list(c('ERV','Self-Antigen'),
                                      c('ERV','SNV'),
                                      c('Self-Antigen','SNV')))+
  ggtitle('Antigens filtered by Wells criteria')+
  theme(axis.title=element_text(face='bold'),
        title=element_text(face='bold'),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x=element_blank())




#Figures 4G-H: Mutational signatures
dirs = list.files()
dirs2 = dirs[substr(dirs,1,4)=='IMGF' & substr(dirs,nchar(dirs)-13,nchar(dirs))=='Best_Model.tsv']

listsigs = data.frame(matrix(nrow = length(dirs2),ncol=14))

#Read in the data and save as a list

for (i in 1:length(dirs2)){
  listsigs[i,] = read.delim(dirs2[i])
}


#Define signatures
sigs = listsigs$X2
sigs = unique(unlist(strsplit(sigs,",")))

#Format as a data frame
dfsigs = data.frame(matrix(nrow=nrow(listsigs),ncol=length(sigs),0))
colnames(dfsigs) = sigs
rownames(dfsigs) = listsigs$X14

#Reformat data

for (i in 1:nrow(dfsigs)){
  specrow = listsigs[i,]
  sigs1 = unlist(strsplit(specrow$X2,","))
  values = unlist(strsplit(specrow$X4,","))
  for (n in 1:length(sigs1)){
    dfsigs[i,colnames(dfsigs)==sigs1[n]] = as.numeric(values[n])
  }
}

#Reformat data frame

df2 = data.frame(rows=rownames(dfsigs)[row(dfsigs)], vars=colnames(dfsigs)[col(dfsigs)],
                 values=unlist(as.vector(dfsigs)))
df2$rows = substr(df2$rows,11,18)
df2[df2$rows == '123_post',]
df2$pre = substr(df2$rows,6,6)=='r'
df2 = df2[order(df2$pre),]


#Etiologies of mutational signatures

m3 = df2
m3$vars='Other'
m3$vars[df2$vars %in% c('SBS2','SBS13')]='APOBEC'
m3$vars[df2$vars %in% c('SBS4')]='Tobacco'
m3$vars[df2$vars %in% c('SBS7a','SBS7b','SBS38')]='UV'
m3$vars[df2$vars %in% c('SBS35')]='Platinum'
m3$vars = factor(m3$vars,levels=c('Other','UV','Tobacco','Platinum','APOBEC'))


#Pre and post

m4 = df2
m4$patient = substr(m4$rows,1,3)
m4post = m4[m4$pre==FALSE,]
m4pre = m4[m4$pre==TRUE,]

#Combine pre and post
m4all=rbind(m4pre,m4post)
m4all$pre[m4all$pre==TRUE] = 'Pre-treatment'
m4all$pre[m4all$pre==FALSE] = 'Post-treatment'
m4all$pre = factor(m4all$pre,levels=c('Pre-treatment','Post-treatment'))


#Etiologies of mutational signatures
m5 = m4all
m5$vars='Other'
m5$vars[m4all$vars %in% c('SBS2','SBS13')]='APOBEC'
m5$vars[m4all$vars %in% c('SBS4')]='Tobacco'
m5$vars[m4all$vars %in% c('SBS7a','SBS7b','SBS38')]='UV'
m5$vars[m4all$vars %in% c('SBS35')]='Platinum'
m5$vars = factor(m5$vars,levels=c('Other','UV','Tobacco','Platinum','APOBEC'))

#Only non-empty rows
m5 = m5[m5$values!=0,]
m5[m5$patient=='144',]

#remove post from pCR

m5 = m5[!(m5$pre=='Post-treatment' & (as.character(m5$patient) %in% clin$Patient[clin$complete_response=='Yes'])),]

#Define response
t2 = clin[clin$Patient %in% m5$patient,]
t2 = t2[!duplicated(t2$Patient),]

t2$Responder = 'NR'
t2$Responder[t2$Pathologic_Responder=='Yes']='PR'
t2$Responder[t2$complete_response=='Yes'] = 'CR'
t2 = t2[order(t2$Patient),]
t3 = t2[t2$Patient %in% m5$patient,]
t3$patient = t3$Patient
table(t3$Responder,t3$Patient)

#Label by response
names = c('111'= 'CR',
          '112'= 'NR',
          '113'= 'CR',
          '114'= 'CR',
          '115'= 'PR',
          '117'= 'PR',
          '119'= 'CR',
          '120'= 'PR',
          '121'= 'NR',
          '122'= 'CR',
          '123'= 'NR',
          '124'= 'NR',
          '125'= 'CR',
          '126'= 'NR',
          '127'= 'PR',
          '128'= 'PR',
          '130'= 'CR',
          '131'= 'NR',
          '133'= 'CR',
          '134' = 'CR',
          '136' = 'CR',
          '137' = 'NR',
          '138'= 'CR',
          '139'= 'PR',
          '140'= 'PR',
          '143'= 'NR',
          '144'= 'NR')



m5 = full_join(m5,t3,by='patient')

m5$patient = factor(m5$patient, levels=unique(m5$patient[order(2*(m5$Responder=='CR')+1*(m5$Responder=='PR'))]))


strip = strip_themed(background_x = elem_list_rect(fill=c(rep('brown',9),rep('yellow',7),rep('orange',11))))

#Figure 4G: pre and post mutational signatures

ggplot(m5,aes(pre, y=values,fill=vars)) +
  geom_bar(stat="identity")+
  theme_bw()+
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))+
  scale_fill_viridis_d(name='Signature',option='turbo')+
  xlab('')+
  ylab('Proportion')+facet_grid2(~patient,strip=strip,scales = "free",
                                 labeller = as_labeller(names))








#Figure 4H: Changes in mutations by etiology

#Read in data

dirs3 = dirs[substr(dirs,1,4)=='IMGF' & substr(dirs,nchar(dirs)-32,nchar(dirs))=='Best_Model_Variant_Signatures.tsv']
listmuts = vector("list",length(dirs3))


for (i in 1:length(dirs3)){
  r = read.delim(dirs3[i])
  r = r[order(-r$Probability),]
  r = r[!duplicated(paste(r$Chr,r$Pos)) & r$Probability>0.5,]
  r$mutation = paste(r$Chr,r$Pos)
  listmuts[[i]] = r
}

#Combine as data frame
mut_df = data.frame(listmuts[[1]]$mutation,listmuts[[1]]$Signature)
colnames(mut_df) = c('Mutation','Signature')
mut_df$Patient = substr(dirs3[1],11,18)

for (i in 2:length(dirs3)){
  mut_dfsigs2 = data.frame(listmuts[[i]]$mutation,listmuts[[i]]$Signature)
  colnames(mut_dfsigs2) = c('Mutation','Signature')
  mut_dfsigs2$Patient = substr(dirs3[i],11,18)
  mut_df = rbind(mut_df,mut_dfsigs2)
}


#Define patient and timepoint

mut_df$timepoint = substr(mut_df$Patient,5,8)
mut_df$patient = substr(mut_df$Patient,1,3)
mut_df = mut_df[mut_df$patient %in% clin$Patient[clin$complete_response!='CR'],]

#Pre vs. post

mut_dfpre = mut_df[mut_df$timepoint=='pre-',]
mut_dfpost = mut_df[mut_df$timepoint=='post',]
mut_dfpre = mut_dfpre[mut_dfpre$patient %in% mut_dfpost$patient,]
mut_dfpost = mut_dfpost[mut_dfpost$patient %in% mut_dfpre$patient,]
mut_dfpre = mut_dfpre[mut_dfpre$patient %in% mut_dfpost$patient,]

patient_list = unique(mut_dfpre$patient)


#PROCESS FIRST PATIENT SAMPLE
{
  patient = patient_list[1]
  mut_dfpre2 = mut_dfpre[mut_dfpre$patient == patient,]
  mut_dfposclin_mut_etio = mut_dfpost[mut_dfpost$patient == patient,]
  
  #Combine into one data frame
  mut_dfpp2 = rbind(mut_dfpre2,mut_dfposclin_mut_etio)
  
  
  #Read in mutation data used for oncoplots
  
  
  #read in .maf file
  maf1520 = read.maf(maf = 'lccc1520.somatic_filtered_merged.maf')
  maf1520_all = maf1520
  
  #protein-coding mutations only
  maf1520 = subsetMaf(maf1520,query = "BIOTYPE=='protein_coding'")
  
  #Cadabra indel quality >10.5, 
  #Mutect2 indel quality >6.8 or SNV quality >9.2,
  #Strelka2 indel quality >15.2 or SNV quality >19.7
  maf1520 = subsetMaf(maf1520,query = "(CADABRA_QUAL>10.5)|
                 (MUTECT2_TLOD > 9.2) | 
                 (Variant_Type %in% c('INS','DEL') & MUTECT2_TLOD>6.8)|
                 (STRELKA2_SomaticEVS > 19.7) | 
                 (Variant_Type %in% c('INS','DEL') & STRELKA2_SomaticEVS>15.2)")
  
  #Remaining variants required at least 5 supporting reads and a minimum read depth of 40,
  #or 10 supporting reads and minimum read depth of 80 if MAF <5%
  maf1520 = subsetMaf(maf1520,query = "((t_alt_count/(t_ref_count))>=0.05 &
                 t_alt_count>=5 & t_depth>=40)|
                 ((t_alt_count/(t_ref_count))<0.05 &
                 t_alt_count>=10 & t_depth>=80)")
  
  #Variants with a MAF>5% in normal tissue were dropped...
  maf1520 = subsetMaf(maf1520,query = "n_alt_count/(n_ref_count)<=0.05")
  
  #...as were variants appearing at rates above 1% in any subpopulation in either
  #GnomAD...
  maf1520 = subsetMaf(maf1520,query = "gnomAD_AFR_AF<=0.01 | is.na(gnomAD_AFR_AF)")
  maf1520 = subsetMaf(maf1520,query = "gnomAD_ASJ_AF<=0.01| is.na(gnomAD_ASJ_AF)")
  maf1520 = subsetMaf(maf1520,query = "gnomAD_FIN_AF<=0.01| is.na(gnomAD_FIN_AF)")
  maf1520 = subsetMaf(maf1520,query = "gnomAD_NFE_AF<=0.01| is.na(gnomAD_NFE_AF)")
  maf1520 = subsetMaf(maf1520,query = "gnomAD_OTH_AF<=0.01| is.na(gnomAD_OTH_AF)")
  maf1520 = subsetMaf(maf1520,query = "gnomAD_SAS_AF<=0.01| is.na(gnomAD_SAS_AF)")
  
  #...or 1000 Genomes databases
  maf1520 = subsetMaf(maf1520,query = "AFR_AF<=0.01| is.na(AFR_AF)")
  maf1520 = subsetMaf(maf1520,query = "AMR_AF<=0.01| is.na(AMR_AF)")
  maf1520 = subsetMaf(maf1520,query = "ASN_AF<=0.01| is.na(ASN_AF)")
  maf1520 = subsetMaf(maf1520,query = "EAS_AF<=0.01| is.na(EAS_AF)")
  maf1520 = subsetMaf(maf1520,query = "EUR_AF<=0.01| is.na(EUR_AF)")
  maf1520 = subsetMaf(maf1520,query = "SAS_AF<=0.01| is.na(SAS_AF)")
  maf1520 = subsetMaf(maf1520,query = "AA_AF<=0.01| is.na(AA_AF)")
  maf1520 = subsetMaf(maf1520,query = "EA_AF<=0.01| is.na(EA_AF)")
  
  #To counter FFPE artifacts, C>T and G>A substitutions required a minimum MAF of 10%
  maf1520 = subsetMaf(maf1520,query = "n_alt_count/n_ref_count + 1*(!((Reference_Allele == 'C' &
             (Tumor_Seq_Allele1=='T'&Tumor_Seq_Allele2=='T')) |
  (Reference_Allele == 'G' &
     (Tumor_Seq_Allele1=='A'&Tumor_Seq_Allele2=='A'))))>=0.1")
  
  #Cosmic Tier 1 bladder listing genes
  genelist = c('TP53','KDM6A','ERBB3','TSC1',
               'STAG2','CDKN2A','NOTCH1','FGFR3',
               'TBL1XR1','ETV6')
  
  #remove old samples with poor QC that have been re-sequenced
  maf1520 = subsetMaf(maf1520,tsb = names(table(maf1520@data$Tumor_Sample_Barcode))[-c(17,31)])
  
  #Label pre and post timepoints
  maf1520@clinical.data$Timepoint = substr(maf1520@clinical.data$Tumor_Sample_Barcode,5,7)
  maf1520@clinical.data$Timepoint[maf1520@clinical.data$Timepoint=='pre']='Pre-Treatment'
  maf1520@clinical.data$Timepoint[maf1520@clinical.data$Timepoint=='pos']='Post-Treatment'
  maf1520@clinical.data$Timepoint[c(23,29,42,47,37,39,44,45,49,50)] = 'Pre-Treatment'
  maf1520@clinical.data$Timepoint[c(15,21,24,31)] = 'Post-Treatment'
  maf1520@clinical.data$Patient = substr(maf1520@clinical.data$Tumor_Sample_Barcode,1,3)
  
  
  
  maf1520_pre = subsetMaf(maf1520,tsb = maf1520@clinical.data$Tumor_Sample_Barcode[maf1520@clinical.data$Timepoint=='Pre-Treatment'])
  
  maf1520_post = subsetMaf(maf1520,tsb = maf1520@clinical.data$Tumor_Sample_Barcode[maf1520@clinical.data$Timepoint=='Post-Treatment' & 
                                                                                      !(maf1520@clinical.data$Patient %in% clin$Patient[clin$complete_response=='Yes'])])
  
  
  
  
  lpre = maf1520_pre@data
  lpost = maf1520_post@data
  
  lpre$Mutation = paste(lpre$Chromosome,lpre$Start_Position)
  lpost$Mutation = paste(lpost$Chromosome,lpost$Start_Position)
  
  maf1520_all_data = maf1520_all@data
  
  maf1520@data$Mutation = paste(maf1520@data$Chromosome,maf1520@data$Start_Position)
  maf1520_all_data$Mutation = paste(maf1520_all_data$Chromosome,maf1520_all_data$Start_Position)
  
  mut_dfpp2 = mut_dfpp2[mut_dfpp2$Mutation %in% maf1520_all_data$Mutation,]
  
  #Identify gained, lost, and retained mutations by signature
  
  gained = mut_dfposclin_mut_etio[(mut_dfposclin_mut_etio$Mutation %in% maf1520@data$Mutation) &
                                    (mut_dfposclin_mut_etio$Mutation %in% lpost$Mutation) &
                                    !(mut_dfposclin_mut_etio$Mutation %in% lpre$Mutation),]
  
  lost = mut_dfpre2[(mut_dfpre2$Mutation %in% maf1520@data$Mutation) &
                      (mut_dfpre2$Mutation %in% lpre$Mutation) &
                      !(mut_dfpre2$Mutation %in% lpost$Mutation),]
  
  retained = mut_dfpp2[(mut_dfpp2$Mutation %in% maf1520_all_data$Mutation) &
                         !(mut_dfpp2$Mutation %in% gained$Mutation) & 
                         !(mut_dfpp2$Mutation %in% lost$Mutation),]
  
}

#PROCESS THE REST OF THE PATIENT SAMPLES

for (i in 2:length(patient_list)){
  patient = patient_list[i]
  mut_dfpre2 = mut_dfpre[mut_dfpre$patient == patient,]
  mut_dfposclin_mut_etio = mut_dfpost[mut_dfpost$patient == patient,]
  mut_dfpp2 = rbind(mut_dfpre2,mut_dfposclin_mut_etio)
  
  gained2 = mut_dfposclin_mut_etio[(mut_dfposclin_mut_etio$Mutation %in% maf1520@data$Mutation) &
                                     (mut_dfposclin_mut_etio$Mutation %in% lpost$Mutation) &
                                     !(mut_dfposclin_mut_etio$Mutation %in% lpre$Mutation),]
  
  lost2 = mut_dfpre2[(mut_dfpre2$Mutation %in% maf1520@data$Mutation) &
                       (mut_dfpre2$Mutation %in% lpre$Mutation) &
                       !(mut_dfpre2$Mutation %in% lpost$Mutation),]
  
  retained2 = mut_dfpp2[(mut_dfpp2$Mutation %in% maf1520_all_data$Mutation) &
                          !(mut_dfpp2$Mutation %in% gained2$Mutation) & 
                          !(mut_dfpp2$Mutation %in% lost2$Mutation),]
  
  gained = rbind(gained,gained2)
  lost = rbind(lost,lost2)
  retained = rbind(retained,retained2)
}

#Label gained, lost, and retained

gained$type = 'Gained'
lost$type = 'Lost'
retained$type = 'Retained'

#Combine the three data frames

glr = rbind(gained,lost,retained)

#Format for plotting

melted = melt(table(glr$Signature,paste(glr$Patient,glr$type)))
melted$Patient = substr(melted$Var2,1,3)

melted$Type = substr(melted$Var2,10,nchar(as.character(melted$Var2)))
melted = melted[,-2]

colnames(melted) = c('Signature','Count','Patient','Type')
clin$complete_response
melted = left_join(melted, clin, by='Patient')
melted = melted[melted$complete_response=='No',]
melted$Response = 'NR'
melted$Response[melted$Pathologic_Responder=='Yes']='PR'

mut_etio2 = melted
mut_etio2$vars='Other'
mut_etio2$vars[mut_etio2$Signature %in% c('SBS2','SBS13')]='APOBEC'
mut_etio2$vars[mut_etio2$Signature %in% c('SBS4')]='Tobacco'
mut_etio2$vars[mut_etio2$Signature %in% c('SBS7a','SBS7b','SBS38')]='UV'
mut_etio2$vars[mut_etio2$Signature %in% c('SBS35')]='Platinum'
mut_etio2$vars = factor(mut_etio2$vars,levels=c('Other','UV','Tobacco','Platinum','APOBEC'))


#Label by response

names = c('111' = 'PR',
          '122' = 'PR',
          '121' = 'NR',
          '123' = 'NR',
          '124' = 'NR',
          '126' = 'NR',
          '131' = 'NR',
          '137' = 'NR',
          '115' = 'PR',
          '117' = 'PR',
          '120' = 'PR',
          '127' = 'PR',
          '128' = 'PR',
          '139' = 'PR',
          '140' = 'PR',
          '112' = 'NR'
)



#Fill in Zero values
zeros = mut_etio2
zeros$Patient = c('124','123','120')
zeros$Response = c('NR','NR','PR')
zeros$Count = 0

mut_etio2 = rbind(zeros,mut_etio2)

mut_etio2 = mut_etio2[order(mut_etio2$Response),]
mut_etio2$Patient = factor(mut_etio2$Patient,levels=unique(mut_etio2$Patient))
mut_etio2$fill='brown'
mut_etio2$fill[mut_etio2$Response=='PR']='yellow'


ggplot(data = mut_etio2, aes(x = Patient, y = Count, fill = vars)) + 
  geom_bar(stat='identity', position = 'stack')+xlab('')+ylab('Mutation Count')+theme_bw()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  scale_fill_viridis_d(name='Signature',option='turbo')+ggtitle('') + 
  facet_grid2(~ Type)+
  scale_x_discrete(breaks=mut_etio2$Patient[!duplicated(mut_etio2$Patient)],
                   labels=mut_etio2$Response[!duplicated(mut_etio2$Patient)])+
  new_scale('fill')+
  geom_tile(data=mut_etio2, aes(x = Patient, y = -50,height=10, fill = fill))+
  scale_fill_manual(values=c('brown','yellow'),labels=c('NR','PR'),name='Response')+
  theme(axis.title=element_text(face='bold'),axis.text.x=element_blank(),axis.ticks.x=element_blank())





```


#Figure 5

```{r}


#Figure 5A: TMB by response

#Read in data
clin = read.csv('Clinical1520.csv')
clin$Patient = as.character(clin$ID)

tmb = read.csv('LCCC1520_TMB.csv')

#Remove old, poor QC reads
tmb = tmb[-c(17,31),]

#Define patient and timepoint
tmb$Patient = substr(tmb$Sample_ID,1,3)
tmb$Timepoint = substr(tmb$Sample_ID,5,7)

#Only pre-treatment samples
tmb_pre = tmb[tmb$Timepoint=='pre',]

#Combine TMB and clinical
clin_tmb = full_join(clin,tmb_pre,by="Patient")

#Add response categories
clin_tmb$Response = 'CR'
clin_tmb$Response[clin_tmb$complete_response=='No'] = 'PR'
clin_tmb$Response[clin_tmb$Pathologic_Responder=='No'] = 'NR'
clin_tmb$Response = factor(clin_tmb$Response,levels=c('CR','PR','NR'))

ggplot(clin_tmb,aes(Response,TMB,fill=Response,col=Response))+
  geom_boxplot(outlier.shape=NA,col='black')+stat_compare_means(comparisons=list(c('PR','CR'),
                                                                                 c('PR','NR'),
                                                                                 c('CR','NR')))+
  scale_fill_manual(values=c('orange','gold','brown'))+
  xlab('')+theme(legend.position='')+
  geom_jitter(alpha=0.5,size=4,height=0,width=0.2,pch=21,col='black')+
  theme(axis.title.y = element_text(face="bold"),
        axis.title.x = element_blank(),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))



#Figure 5B: TMB by Adverse Event

clin_tmb$adverse = clin_tmb$Reason_chemotherapy_ended=="Adverse events / Side effects (specify in Comments)"
clin_tmb$adverse[clin_tmb$Reason_chemotherapy_ended=='']=NA
clin_adv = clin_tmb[!is.na(clin_tmb$adverse),]
clin_adv$adverse2='None'
clin_adv$adverse2[clin_adv$adverse==TRUE]='Adverse Event'

ggplot(clin_adv,aes(adverse2,TMB,fill=adverse2))+
  geom_boxplot(outlier.shape=NA,alpha=0.2)+
  stat_compare_means(comparisons=list(c('Adverse Event','None')))+                                                                                              
  scale_fill_manual(values=c('magenta','navy'))+
  scale_color_manual(values=c('magenta','navy'))+
  xlab('')+theme(legend.position='')+
  geom_jitter(alpha=0.5,size=4,height=0,width=0.2,aes(col=adverse2))+
  theme(axis.title.y = element_text(face="bold"),
        axis.title.x = element_blank(),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))


#Figure 5C-D: Gene expression by response

expr = read.csv('LCCC1520_expr.csv')

#Select just PD-L1 and TIGIT
genes_of_interest = expr[,colnames(expr) %in% c('X','CD274.29126','TIGIT.201633')]
genes_of_interest$X
genes_of_interest$Patient = substr(genes_of_interest$X,1,3)
genes_of_interest$Timepoint = substr(genes_of_interest$X,nchar(genes_of_interest$X)-4,nchar(genes_of_interest$X)-2)

#Select on pre-treatment samples
goi2 = genes_of_interest[genes_of_interest$Timepoint=='pre',]

#Combine clinical and gene expression data
clin_gene = full_join(clin,goi2,by="Patient")

#Add response categories
clin_gene$Response = 'CR'
clin_gene$Response[clin_gene$complete_response=='No'] = 'PR'
clin_gene$Response[clin_gene$Pathologic_Responder=='No'] = 'NR'
clin_gene$Response = factor(clin_gene$Response,levels=c('CR','PR','NR'))


#Figure 5C: PD-L1 vs. Response

ggplot(clin_gene,aes(Response,CD274.29126,fill=Response))+
  geom_boxplot(outlier.shape=NA,alpha=0.2)+
  stat_compare_means(comparisons=list(c('PR','CR'),c('PR','NR'),c('CR','NR')))+
  ylab('log2 PD-L1 expression')+
  scale_fill_manual(values=c('orange','gold','brown'))+xlab('')+theme(legend.position='')+
  geom_jitter(alpha=0.5,size=4,height=0,pch=21,col='black',aes(fill=Response))+
  theme(axis.title.y = element_text(face="bold"),
        axis.title.x = element_blank(),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))


#Figure 5D: TIGIT vs. Response

ggplot(clin_gene,aes(Response,TIGIT.201633,fill=Response))+
  geom_boxplot(outlier.shape=NA,alpha=0.2)+
  stat_compare_means(comparisons=list(c('PR','CR'),c('PR','NR'),c('CR','NR')))+
  ylab('log2 TIGIT expression')+
  scale_fill_manual(values=c('orange','gold','brown'))+xlab('')+theme(legend.position='')+
  geom_jitter(alpha=0.5,size=4,height=0,pch=21,col='black',aes(fill=Response))+
  theme(axis.title.y = element_text(face="bold"),
        axis.title.x = element_blank(),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))



#Figure 5E: Ayers_IFNG by response

#Read in data
igs = read.delim('LCCC1520_immune_score.txt',header=T,sep='\t')
#Define patient and timepoint
igs$Patient = substr(igs$X,1,3)
igs$timepoint = substr(igs$X,nchar(igs$X)-3,nchar(igs$X)-3)
igs$timepoint[igs$timepoint == 'r'] = 'pre'
igs$timepoint[igs$timepoint == 's'] = 'post'

#remove old samples with poor QC that have been re-sequenced
igs = igs[-c(17,33),]

#select only pre-treatment IGS
igs_pre = igs[igs$timepoint=='pre',]

#Combine IGS and clinical
clin_igs = full_join(clin,igs_pre,by="Patient")

#Add response categories
clin_igs$Response = 'CR'
clin_igs$Response[clin_igs$complete_response=='No'] = 'PR'
clin_igs$Response[clin_igs$Pathologic_Responder=='No'] = 'NR'
clin_igs$Response = factor(clin_igs$Response,levels=c('CR','PR','NR'))

ggplot(clin_igs,aes(Response,Ayers_IFNG,fill=Response))+
  geom_boxplot(outlier.shape=NA,alpha=0.2)+stat_compare_means(comparisons=list(c('PR','CR'),
                                                                               c('PR','NR'),
                                                                               c('CR','NR')))+
  scale_fill_manual(values=c('orange','gold','brown'))+xlab('')+theme(legend.position='')+
  geom_jitter(alpha=0.5,size=4,height=0,pch=21,col='black')+
  theme(axis.title.y = element_text(face="bold"),
        axis.title.x = element_blank(),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))



#Figure 5F: Consensus subtype vs. response

#Read in data
subtypes = read.delim('LCCC1520_subtype.txt',header=T)

#Define patient and timepoint
subtypes$Patient=substr(subtypes$ID,1,3)
subtypes$timepoint=substr(subtypes$ID,5,7)
subtypes$timepoint[subtypes$timepoint=='RE_'] = 'pos'
#remove old samples with poor QC that have been re-sequenced
subtypes = subtypes[-c(17,33),]

#Subset pre-treatment subtypes
subtypes_pre = subtypes[subtypes$timepoint=='pre',]

#Combine clinical and subtype data
clin_sub = full_join(clin,subtypes_pre,by='Patient')

#Add response categories
clin_sub$Response = 'CR'
clin_sub$Response[clin_sub$complete_response=='No'] = 'PR'
clin_sub$Response[clin_sub$Pathologic_Responder=='No'] = 'NR'
clin_sub$Response = factor(clin_sub$Response,levels=c('CR','PR','NR'))

#barplot for only response/NR

cstab = table(clin_sub$Response,clin_sub$Consensus)
cstab_df = data.frame(cstab)

#fisher exact test
pval = paste('p = ',round(fisher.test(cstab)$p.value,3),sep='')

#stacked barplot of response
ggplot(cstab_df, aes(x = Var1, y = Freq, fill = factor(Var2), label = Freq)) +
  geom_bar(position = position_fill(reverse = TRUE), stat="identity") + xlab(pval) + ylab('Proportion') + 
  scale_fill_discrete(name = "")+
  ggtitle('Pre-Treatment\nConsensus Subtype')+
  geom_text(data=subset(cstab_df,Freq != 0), aes(label = Freq), position = position_fill(vjust = 0.5,reverse=T))+
  scale_fill_manual(values=c("#FF1D1E","#237BFE","#20FF78","#D2FF1F"),name='')+
  theme(axis.title.y = element_text(face="bold"),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))


#Figure 5G: Survival by response and gender

clin$Responder = 'NR'
clin$Responder[clin$Pathologic_Responder=='Yes'] = 'Responder'
fit_gender_resp = survfit(Surv(OStimemonths,OSstat)~Responder+Gender,clin)

#Create table of p-value comparisons between survival curves
res_table = as.data.frame(pairwise_survdiff(Surv(OStimemonths, OSstat) ~ Responder+Gender, data = clin)$p.value)
res_table = round(res_table,4)
colnames(res_table) = c('Female NR','Male NR','Female\nResponder')
rownames(res_table) = c('Male NR','Female Responder','Male Responder')
res_table[is.na(res_table)]=''

ggsurvplot(fit_gender_resp,pval=FALSE,size=1.5,censor.size=8,
           legend.title='',
           legend.labs = c("Female NR","Male NR","Female Responder","Male Responder"),
           xlab = 'Time (months)',
           palette='jco')$plot+
  geom_table(label=list(res_table),x = 50, y = 0.1,table.rownames=TRUE,table.colnames = TRUE)



#Figure 5H-J: Elastic net models of survival and response

#Combine clinical, IGS, and subtypes
ics = full_join(igs_pre,clin_sub,by='Patient')

#Checkpoint genes

expr2 = expr[,colnames(expr) %in% c('PDCD1.5133','CD274.29126','TIGIT.201633','LAG3.3902','HAVCR2.84868','CTLA4.1493',
                                    'VSIR.64115')]
colnames(expr2) = c('PD-1','PD-L1','TIGIT','LAG3','TIM3','CTLA4','VISTA')
expr2$Patient= subtypes$Patient
expr2$timepoint =subtypes$timepoint
expr2 = expr2[expr2$timepoint=='pre',]

#Incorporate checkpoint gene expression
icse = full_join(ics,expr2,'Patient')
icse=icse[!is.na(icse$X),]

#Incorporate TMB data
tmb$timepoint = 'pre'
tmb$timepoint[substr(tmb$Sample_ID,6,6)=='o']='post'
tmb_pre = tmb[tmb$timepoint=='pre',]

icse_tmb = full_join(icse,tmb_pre,by="Patient")

#Binarize categorical variables
icse_tmb$Age = icse_tmb$Age_at_On_Study
icse_tmb$ECOG.0 = 1*(icse_tmb$ECOG_Performance_Status=="0-Fully active")
icse_tmb$Gender.M = 1*(icse_tmb$Gender=='M')
icse_tmb$T2 = 1*(substr(icse_tmb$Clinical_T_stage,1,2)=='T2')
icse_tmb$Current_Smoker[icse_tmb$Ever_Smoked=='No'] = 0
icse_tmb$Current_Smoker[icse_tmb$Current_Smoker=='No'] = 0
icse_tmb$Current_Smoker[icse_tmb$Current_Smoker=='Yes'] = 1
icse_tmb$Ever_Smoked = 1*(icse_tmb$Ever_Smoked=='Yes')
icse_tmb$Consensus.BaSq = 1*(icse_tmb$Consensus=='Ba/Sq')
icse_tmb$Consensus.LumP = 1*(icse_tmb$Consensus=='LumP')
icse_tmb$Consensus.StromaRich = 1*(icse_tmb$Consensus=='Stroma-rich')
icse_tmb$response = 1*(icse_tmb$Pathologic_Responder=='Yes')
icse_tmb$os = icse_tmb$OStimemonths
icse_tmb$censOS = icse_tmb$OSstat

#Select relevant columns
icse_tmb = icse_tmb[,-c(1,31,63:65,68:90,98:99,101:102)]


#Figure 5H: Response Model

train = na.omit(icse_tmb[,-c(ncol(icse_tmb)-1,ncol(icse_tmb))])

for (j in 1:(ncol(train)-1)){
  train[,j] = as.numeric(scale(as.numeric(train[,j])))
}


set.seed(3456)

control <- trainControl(method='repeatedcv', 
                        number=10, 
                        repeats=1)


train$response = factor(train$response)

elnet = train(
  response~., data = train,
  method = "glmnet",
  trControl = control,
  tuneLength=15
)

plotit = data.frame(as.matrix(coef(elnet$finalModel, elnet$bestTune$lambda)))
alph = elnet$bestTune$alpha
lambd = elnet$bestTune$lambda
plotit$names = rownames(plotit)
colnames(plotit)[1] = 'means'
plotit$fills = plotit$means>0
plotit$fills[plotit$fills==TRUE] = 'Better'
plotit$fills[plotit$fills==FALSE] = 'Worse'
plotit = plotit[plotit$means!=0,]
plotit = plotit[-1,]

#Cross-validate model

Train = train
TrainX = train[,colnames(train)!='response']
TrainY = Train$response
fit = coef(elnet$finalModel, elnet$finalModel$lambdaOpt)
coeffs = data.frame(matrix(nrow = nrow(fit), ncol = 10))
rownames(coeffs) = rownames(fit)

dataset=train
x = dataset[,colnames(dataset)!='response'] #no response
y = dataset$response

#Randomly shuffle the data
Train = Train[sample(nrow(Train)),]

#Create 10 folds
folds = cut(seq(1,nrow(Train)),breaks=10,labels=FALSE)

#Perform 10 fold CV
alph = elnet$bestTune$alpha
lambd = elnet$bestTune$lambda

for(i in 1:10){
  testIndexes = which(folds==i,arr.ind=TRUE)
  trainX = model.matrix(~.,Train[-testIndexes,-ncol(Train)])
  trainY = as.numeric(na.omit(Train[-testIndexes,ncol(Train)]))-1
  fit = glmnet(trainX, trainY, alpha = alph, lambda = lambd)
  coeffs[,i] = as.vector(fit$beta)
}

means = rowSums(coeffs)/10
stds = rowSds(as.matrix(coeffs))

n = 10
names = names(means)
df_plotvars = data.frame(names,means,stds)
df_plotvars$error = qnorm(0.975)*stds/sqrt(n)
df_plotvars$ci_lo = df_plotvars$means - df_plotvars$error
df_plotvars$ci_hi = df_plotvars$means + df_plotvars$error
df_plotvars$CI_crosses_zero = (df_plotvars$ci_lo*df_plotvars$ci_hi)<=0
df_plotvars$fills = factor(df_plotvars$means>0, labels=c("Worse", "Better"))
df_plotvars$names[df_plotvars$names=='`PD-1`'] = 'PD-1'
df_plotvars$names[df_plotvars$names=='IL_8'] = 'IL-8 signature'

df_CI = df_plotvars[df_plotvars$CI_crosses_zero == FALSE,] #variables with CIs that don't cross 0

coeffs2 = coeffs[rownames(coeffs) %in% c(df_CI$names,'`PD-1`','IL_8'),]
coeffs3 = data.frame(unlist(coeffs2))
coeffs2
coeffs3
colnames(coeffs3) = 'value'
coeffs3$names = rep(rownames(coeffs2),10)
coeffs3$names[coeffs3$names=='`PD-1`']='PD-1'
coeffs3$names[coeffs3$names=='IL_8']='IL-8 signature'

coeffs4 = full_join(coeffs3,df_CI,by='names')
coeffs4 = coeffs4[order(-coeffs4$means),]
coeffs4$names = factor(coeffs4$names,levels=unique(coeffs4$names))
ggplot(coeffs4,aes(x=names,y=value))+
  coord_flip()+
  geom_errorbar(aes(x=names, ymin=ci_lo, ymax=ci_hi), width=0.4, colour="gray", alpha=0.9, size=1.3)+
  geom_jitter(data=coeffs4,width=0.2,aes(col=fills),alpha=0.5)+
  geom_bar(data=df_CI,aes(x=names, y=means,fill=fills), stat="identity", alpha=0.3) +
  scale_fill_manual(values=c('black','red'),name='Response')+
  scale_color_manual(values=c('black','red'),name='Response')+
  theme_bw()+theme(panel.grid = element_blank(),title=element_text(face='bold'))+
  ggtitle('Elastic Net Coefficients\n(CV=10, alpha=0.357,\nlambda=0.201)')+
  xlab('Model Features')+ylab('Beta Coefficient')


df_CI$names[df_CI$names=='IL-8 signature']='IL_8'
which_train = train[,colnames(train) %in% df_CI$names]
which_train = which_train[,order(colnames(which_train))]
df_CI = df_CI[order(df_CI$names),]

which_train$pred = 0
for (i in 1:nrow(which_train)){
  which_train$pred[i] = sum(which_train[i,1:10]*df_CI$means)
}

which_train$response = train$response

#Figure 5I: ROC of response model

roc_response = roc(which_train$response~which_train$pred)
plot(roc_response,print.auc=T)


#Figure 5J: Model of survival

#Training set for model of survival (no response)
train = na.omit(icse_tmb[,-c(ncol(icse_tmb)-2)])

#Scale variables
for (j in 1:(ncol(train)-2)){
  train[,j] = as.numeric(scale(as.numeric(train[,j])))
}


#variable, lambda, alpha selection

x = train[,c(1:(ncol(train)-2))] #no os, censOS
y = train$os
x_train = as.data.frame(x)
trainX = model.matrix(~.,x_train)
trainY = y
trainS = train$censOS

set.seed(3456)

df = data.frame(matrix(ncol = 3, nrow = 10))
colnames(df) = c('alpha', 'lambda', 'p_likelihood')
for(i in 1:nrow(df)){
  a = (-1/(nrow(df)-1))+i/(nrow(df)-1)
  cv.fit = cv.glmnet(trainX, Surv(trainY,trainS), family= "cox", alpha = a)
  df$alpha[i] = a
  df$lambda[i] = cv.fit$lambda.min
  df$p_likelihood[i] = min(cv.fit$cvm)
}

#Find optimal lambda and alpha values
lambd = df$lambda[which.min(df$p_likelihood)]
alph = df$alpha[which.min(df$p_likelihood)]

#predictions from model
best_fit = glmnet(trainX, Surv(trainY,trainS), family = "cox", alpha = alph, lambda = lambd)
index = c((which(!best_fit$beta==0)-1),(ncol(train)-1):(ncol(train)))
cp_train = as.data.frame(train[,index])

# Create survival estimates on discovery data
cox_model = coxph(Surv(os,censOS)~., data = cp_train)


fit_surv = glmnet(trainX, Surv(trainY,trainS), family = "cox", alpha = alph, lambda = lambd)
coeffs = data.frame(matrix(nrow = length(fit_surv$beta), ncol = 10))
rownames(coeffs) = rownames(fit$beta)


#Cross-validation

#Create 10 folds
folds = cut(seq(1,nrow(train)),breaks=10,labels=FALSE)

for(i in 1:10){
  testIndexes = which(folds==i,arr.ind=TRUE)
  Train = train[-testIndexes,]
  trainX = model.matrix(~.,Train[,-c(ncol(Train)-1,ncol(Train))])
  trainY = Train$os
  trainS = Train$censOS
  fit = glmnet(trainX, Surv(trainY,trainS), family = "cox", alpha = alph, lambda = lambd)
  coeffs[,i] = as.vector(fit$beta)
}

means = rowSums(coeffs)/10
stds = rowSds(as.matrix(coeffs))

n = 10
names = names(means)
df_surv = data.frame(names,means,stds)
df_surv$error = qnorm(0.975)*stds/sqrt(n)
df_surv$ci_lo = df_surv$means - df_surv$error
df_surv$ci_hi = df_surv$means + df_surv$error
df_surv$CI_crosses_zero = (df_surv$ci_lo*df_surv$ci_hi)<=0
df_surv$fills = factor(df_surv$means>0, labels=c("Better","Worse"))

df_surv_CI = df_surv[df_surv$CI_crosses_zero == FALSE,] #only plot variables with CIs that don't cross 0
df_surv_CI$names[df_surv_CI$names=='`PD-1`'] = 'PD-1'


coeffs2 = coeffs[rownames(coeffs) %in% c(df_surv_CI$names,'`PD-1`'),]
coeffs3 = data.frame(unlist(coeffs2))
colnames(coeffs3) = 'value'
coeffs3$names = rep(rownames(coeffs2),10)
coeffs3$names[coeffs3$names=='`PD-1`']='PD-1'

coeffs4 = full_join(coeffs3,df_surv_CI,by='names')
coeffs4 = coeffs4[order(-coeffs4$means),]
coeffs4$names = factor(coeffs4$names,levels=unique(coeffs4$names))
ggplot(coeffs4,aes(x=names,y=value))+
  coord_flip()+
  geom_errorbar(aes(x=names, ymin=ci_lo, ymax=ci_hi), width=0.4, colour="darkgray", size=1.3)+
  geom_point(data=coeffs4,aes(col=fills),alpha=0.3)+
  geom_bar(data=df_surv_CI,aes(x=names, y=means,fill=fills), stat="identity", alpha=0.3) +
  scale_fill_manual(values=c('red','black'),name='Survival')+
  scale_color_manual(values=c('red','black'),name='Survival')+
  theme_bw()+theme(panel.grid = element_blank(),title=element_text(face='bold'))+
  ggtitle('Elastic Net Coefficients\n(CV=10, alpha=0.111,\nlambda=0.202)')+
  xlab('Model Features')+ylab('Beta Coefficient')




```


#Figure 6

```{r}


#Read in ABACUS IGS, rfs, and clinical data

abacus = read.delim('ABACUS_immune_score.txt',header=T)
abacus_rfs = read.delim('ABACUS_rfs.txt',header=T,sep=',')
abacus_clin = read.delim('ABACUS_clin.txt',header=T,sep=',')

#Join data
acr = full_join(abacus_rfs,abacus_clin,by='subjectId',multiple="all")
acr$X = acr$alias
ac = full_join(abacus,acr,by='X')

#Read in ABACUS RNAseq data

abacus_rna = read.delim('ABACUS_RNAseq.txt',header=T)
abacus_rna = as.data.frame(t(abacus_rna))
colnames(abacus_rna) = abacus_rna[1,]
abacus_rna = abacus_rna[-1,]
abacus_rna_ic = abacus_rna[,colnames(abacus_rna)%in%c('CD274','PDCD1','CTLA4','TIGIT','LAG3','HAVCR2')]
abacus_rna_ic$X = abacus$X

#Join expression with other data
ac = left_join(ac,abacus_rna_ic,by='X')

#Read in subtype data
ac_sub = read.delim('ABACUS_subtypes.txt',header=T)
colnames(ac_sub)[1] = 'X'

#Join subtypes with other data
ac = full_join(ac,ac_sub,by='X')

#binarize Consensus subtypes
ac$Consensus.BaSq = 1*(ac$Consensus=='Ba/Sq')
ac$Consensus.StromaRich = 1*(ac$Consensus=='Stroma-rich')
ac$Consensus.LumU = 1*(ac$Consensus=='LumU')
ac$Consensus.LumP = 1*(ac$Consensus=='LumP')


#Define response
ac$response = 1*(ac$PCR.y == 'Yes'|ac$MPR=='Yes')

#Only pre-treatment samples
ac = ac[ac$VISIT == 'PRE',]

#Only relevant columns
ac = ac[,c(2:30,32:62,84:89,78,96:100)]
colnames(ac)

#Scale the immune gene signatures, TMB, and expression data
for (j in c(2:67)){
  ac[,j] = as.numeric(scale(as.numeric(ac[,j])))
}

colnames(ac)[colnames(ac)=='HAVCR2']='TIM3'


#Read in LCCC1520 IGS data
lc_igs = read.delim('LCCC1520_immune_score.txt',header=T,sep='\t')
lc_igs$pre=substr(lc_igs$X,nchar(lc_igs$X)-2,nchar(lc_igs$X)-2)=='e'
lc_igs$Patient = as.character(substr(lc_igs$X,1,3))

#Only pre-treatment samples
lc_igs = lc_igs[lc_igs$pre==TRUE,]

#Read in LCCC1520 clinical data
lccc_clin = read.csv('Clinical1520.csv')
lccc_clin$Patient = as.character(lccc_clin$ID)

#Read in LCCC1520 expression data
lc_rna = read.csv('LCCC1520_expr.csv',header=T)

#Select text part of gene name
colnames(lc_rna) = sub("\\..*", "", colnames(lc_rna))

lc_rna$Patient = substr(lc_rna$X,1,3)
lc_rna$pre = substr(lc_rna$X,nchar(lc_rna$X)-2,nchar(lc_rna$X)) == 'etx'

lc_ic = lc_rna[,colnames(lc_rna) %in% c('Patient','pre','CD274','PDCD1','CTLA4','TIGIT','LAG3','HAVCR2')]
colnames(lc_ic)[3] = 'TIM3'

#Just pre-treatment samples
lc_ic = lc_ic[lc_ic$pre==TRUE,]

#Combine data sets
lc = right_join(lc_igs,lccc_clin,by='Patient')
lc = full_join(lc,lc_ic,by="Patient")

#Read in subtype data
subtypes = read.delim('LCCC1520_subtype.txt')

#Define patient and timepoint
subtypes$Patient=substr(subtypes$ID,1,3)
subtypes$timepoint=substr(subtypes$ID,5,7)
subtypes$timepoint[c(19,35)] = 'pos'

#Remove old low-QC samples
subtypes = subtypes[-c(17,33),]

#Select only pre-treatment samples
subtypes = subtypes[subtypes$timepoint=='pre',]

#Binarize categorical Consensus subtypes
subtypes$Consensus.BaSq = 1*(subtypes$Consensus=='Ba/Sq')
subtypes$Consensus.StromaRich = 1*(subtypes$Consensus=='Stroma-rich')
subtypes$Consensus.LumU = 1*(subtypes$Consensus=='LumU')
subtypes$Consensus.LumP = 1*(subtypes$Consensus=='LumP')

#Join subtypes with other data
lc = full_join(lc,subtypes,by="Patient")

#Read in TMB data
tmb = read.csv('LCCC1520_TMB.csv')
tmb$Patient = substr(tmb$Sample_ID,1,3)
tmb = tmb[substr(tmb$Sample_ID,7,7)=='e',]

#Join tmb with other data
lc = full_join(lc,tmb,by="Patient")

#Scale the immune gene signatures, TMB, and expression data
for (j in c(2:62,82:87,102)){
  lc[,j] = as.numeric(scale(as.numeric(lc[,j])))
}
colnames(lc)
#Select relevant columns
lc = lc[,c(2:30,32:62,82:87,102,97:100,78)]

#rename response column
colnames(lc)[ncol(lc)]='response'
lc$response = 1*(lc$response=='Yes')




#ABACUS: calculate coefficient and error of each feature's association with response

acdf = data.frame(matrix(nrow=71,ncol=4))
colnames(acdf) = c('sig','coeff','p','error')
acdf$sig = colnames(ac)[1:71]

for (j in 1:71){
  var = ac[,j]
  res = ac$response
  dat = summary(lm(res~var))$coefficients
  acdf$coeff[j] = dat[2,1]
  acdf$p[j] = dat[2,4]
  acdf$error[j] = dat[2,2]*1.386
}

#LCCC1520: calculate coefficient and error of each feature's association with response

lcdf = data.frame(matrix(nrow=71,ncol=4))
colnames(lcdf) = c('sig','coeff','p','error')
lcdf$sig = colnames(lc)[1:71]


for (j in 1:71){
  var = lc[,j]
  res = lc$response
  dat = summary(lm(res~var))$coefficients
  lcdf$coeff[j] = dat[2,1]
  lcdf$p[j] = dat[2,4]
  lcdf$error[j] = dat[2,2]*1.386
}


#Figure 6A: Compare LCCC1520 and ABACUS coefficients of response

lcac = full_join(lcdf,acdf,by='sig')

#Color based on non-overlapping confidence intervals
lcac$higherx = lcac$coeff.x>lcac$coeff.y
lcac$color = (lcac$higherx==TRUE & (lcac$coeff.x-lcac$error.x > lcac$coeff.y+lcac$error.y)) | (lcac$higherx==FALSE & (lcac$coeff.x+lcac$error.x < lcac$coeff.y-lcac$error.y))
lcac$color[lcac$color==FALSE] = 'gray'
lcac$color[lcac$color==TRUE] = 'red'

lcac$alpha = (lcac$color!='gray')
lcac$sig[lcac$color=='gray']=''
lcac$font = 'bold'
lcac$font[lcac$p.x<0.05 | lcac$p.y<0.05] = 'bold'
lcac$lty = '1'
lcac$lty[lcac$color=='gray']='2'
lcac=lcac[!is.na(lcac$color),]
lcac$sig[lcac$sig=='IL_8']='IL_8 signature'

#Remove NS outliers
lcac = lcac[lcac$error.y<1000 & lcac$error.x<1000,]

ggplot(lcac,aes(x=coeff.x,y=coeff.y,label=sig,alpha=alpha))+geom_rect(aes(xmin=coeff.x-error.x,xmax = coeff.x+error.x, ymin=coeff.y-error.y,
                                                                          ymax = coeff.y+error.y,color=color,fill=color,linetype=lty))+
  scale_color_manual(values=c('gray','red'))+
  scale_fill_manual(values=c('gray','red'))+
  theme_bw()+
  geom_abline(slope=1,lty=2)+
  scale_alpha_manual(values=c('TRUE'=0.5,'FALSE'=0))+
  xlab('NAC-ICI (LCCC1520)')+
  ylab('Neoadjuant ICI (ABACUS)')+
  ggtitle('Pre-Treatment Coefficient of Response')+
  theme(legend.position = '',
        axis.title=element_text(face='bold'),
        title=element_text(face='bold'))+
  geom_text_repel(color='black',aes(fontface=font),max.overlaps=100)


#Figure 6B: IL_8 signature (continuous) vs. response

#combine ABACUS and LCCC1520 data
ac$dataset = 'IO-only'
lc$dataset= 'Chemo-IO'
ac_lc = rbind(lc,ac)


ggplot(ac_lc,aes(IL_8,response,col=dataset))+
  geom_jitter(width=0,height=0.1,alpha=0.6,size=3)+
  geom_smooth(aes(col=dataset,fill=dataset))+
  xlab('IL-8 signature')+
  scale_fill_manual(values=c('darkgreen','purple'),guide='none')+
  scale_color_manual(values=c('darkgreen','purple'),
                     labels=c('NAC-ICI','Neoadjuvant ICI'))+
  theme(legend.title=element_blank(),
        axis.title.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.y=element_blank(),
        axis.title.x = element_text(face="bold",color="black"),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_blank(), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  annotate("text", x=-1.5, y=1.2, label= "Response")+
  annotate("text", x=-1.3, y=-0.2, label= "No Response")




#Figure 6C-D: compare IL-8 high and low

#Define IL-8 high
ac$IL8high = ac$IL_8 >= median(na.omit(ac$IL_8))
lc$IL8high = lc$IL_8 >= median(na.omit(lc$IL_8))
ac_lc = rbind(lc,ac)

IL8high = ac_lc[ac_lc$IL8high==TRUE,]
IL8low = ac_lc[ac_lc$IL8high==FALSE,]


#Figure 6C: IL-8 high

il8tab = table(IL8high$dataset,IL8high$response)
il8tab_df = data.frame(il8tab)

#fisher exact test
pval = paste('p = ',round(fisher.test(il8tab)$p.value,3),sep='')
il8tab_df$Var2 = factor(il8tab_df$Var2,levels=c(1,0))
il8tab_df$Var1 = c('NAC-ICI','Neoadjuvant ICI')

#stacked barplot of response
ggplot(il8tab_df, aes(x = Var1, y = Freq, fill = factor(Var2), label = Freq)) +
  geom_bar(position = position_fill(reverse = TRUE), stat="identity") + xlab(pval) + ylab('Proportion') + 
  scale_fill_discrete(name = "")+
  ggtitle('IL_8 signature >= median')+
  geom_text(data=subset(il8tab_df,Freq != 0), aes(label = Freq), position = position_fill(vjust = 0.5,reverse=T))+
  scale_fill_manual(values=c('orchid','brown'),name='',labels=c('Response','NR'))+
  theme(axis.title.y = element_text(face="bold"),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))




#Figure 6D: IL-8 low

il8tab = table(IL8low$dataset,IL8low$response)
il8tab_df = data.frame(il8tab)


#fisher exact test
pval = paste('p = ',round(fisher.test(il8tab)$p.value,3),sep='')
il8tab_df$Var2 = factor(il8tab_df$Var2,levels=c(1,0))
il8tab_df$Var1 = c('NAC-ICI','Neoadjuvant ICI')

#stacked barplot of response
ggplot(il8tab_df, aes(x = Var1, y = Freq, fill = factor(Var2), label = Freq)) +
  geom_bar(position = position_fill(reverse = TRUE), stat="identity") + xlab(pval) + ylab('Proportion') + 
  scale_fill_discrete(name = "")+
  ggtitle('IL_8 signature < median')+
  geom_text(data=subset(il8tab_df,Freq != 0), aes(label = Freq), position = position_fill(vjust = 0.5,reverse=T))+
  scale_fill_manual(values=c('orchid','brown'),name='',labels=c('Response','NR'))+
  theme(axis.title.y = element_text(face="bold"),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))



#Figure 6E-F: stroma-rich subtype by response and dataset

csr = ac_lc[ac_lc$Consensus.StromaRich==1,]
oth = ac_lc[ac_lc$Consensus.StromaRich==0,]

#Figure 6E: Consensus stroma-rich subtype
subtab = table(csr$dataset,csr$response)
subtab_df = data.frame(subtab)

#fisher exact test
pval = paste('p = ',round(fisher.test(subtab)$p.value,3),sep='')
subtab_df$Var2 = factor(subtab_df$Var2,levels=c(1,0))
subtab_df$Var1 = c('NAC-ICI','Neoadjuvant ICI')

#stacked barplot of response
ggplot(subtab_df, aes(x = Var1, y = Freq, fill = factor(Var2), label = Freq)) +
  geom_bar(position = position_fill(reverse = TRUE), stat="identity") + xlab(pval) + ylab('Proportion') + 
  scale_fill_discrete(name = "")+
  ggtitle('Consensus Subtype: Stroma-Rich')+
  geom_text(data=subset(subtab_df,Freq != 0), aes(label = Freq), position = position_fill(vjust = 0.5,reverse=T))+
  scale_fill_manual(values=c('orchid','brown'),name='',labels=c('Response','NR'))+
  theme(axis.title.y = element_text(face="bold"),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))




#Figure 6F: Consensus other subtype
subtab = table(oth$dataset,oth$response)
subtab_df = data.frame(subtab)

#fisher exact test
pval = paste('p = ',round(fisher.test(subtab)$p.value,3),sep='')
subtab_df$Var2 = factor(subtab_df$Var2,levels=c(1,0))
subtab_df$Var1 = c('NAC-ICI','Neoadjuvant ICI')

#stacked barplot of response
ggplot(subtab_df, aes(x = Var1, y = Freq, fill = factor(Var2), label = Freq)) +
  geom_bar(position = position_fill(reverse = TRUE), stat="identity") + xlab(pval) + ylab('Proportion') + 
  scale_fill_discrete(name = "")+
  ggtitle('Consensus Subtype: Stroma-Rich')+
  geom_text(data=subset(subtab_df,Freq != 0), aes(label = Freq), position = position_fill(vjust = 0.5,reverse=T))+
  scale_fill_manual(values=c('orchid','brown'),name='',labels=c('Response','NR'))+
  theme(axis.title.y = element_text(face="bold"),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))






```


#Supp. Fig. 1

```{r}


subtypes = read.delim('LCCC1520_subtype.txt',header=T)

#Define patient and timepoint
subtypes$Patient=substr(subtypes$ID,1,3)
subtypes$timepoint=substr(subtypes$ID,5,7)
subtypes$timepoint[subtypes$timepoint=='RE_'] = 'pos'
#remove old samples with poor QC that have been re-sequenced
subtypes = subtypes[-c(17,33),]

#Pre vs. post subtypes
subtypes2 = subtypes[subtypes$timepoint=='pre',]
subtypes3 = subtypes[subtypes$timepoint=='pos',]

colnames(subtypes3)[colnames(subtypes3)=='Consensus'] = 'Consensus.post'

subtypes5 = full_join(subtypes2,subtypes3,by='Patient')
dim(subtypes5)


#Read in clinical data
clinical = read.csv('Clinical1520.csv')
clinical$Patient= as.character(clinical$ID)

#Define response class
noncr = clinical$Patient[clinical$complete_response==0]
pr = clinical$Patient[clinical$Pathologic_Responder==1]
nr = clinical$Patient[clinical$Pathologic_Responder==0]

#Remove NAs
subtypes5$Patient = substr(subtypes5$ID.x,1,3)
subtypes5 = na.omit(subtypes5)

#Read in ploidy/cellularity data
cellularity_data = read.csv('ploidy.csv')
cellularity_data$Timepoint = substr(cellularity_data$Patient,1,2) == 'pr'
cellularity_data$Timepoint[cellularity_data$Timepoint==TRUE] = 'Pre-Treatment'
cellularity_data$Timepoint[cellularity_data$Timepoint==FALSE] = 'Post-Treatment'
cellularity_data$Timepoint = factor(cellularity_data$Timepoint,levels=c('Pre-Treatment','Post-Treatment'))

#Define patient
cellularity_data$Patient = substr(cellularity_data$Patient,nchar(cellularity_data$Patient)-2,nchar(cellularity_data$Patient))
cellularity_data2 = cellularity_data[cellularity_data$Patient %in% cellularity_data$Patient[duplicated(cellularity_data$Patient)],]
subtypes5 = subtypes5[subtypes5$Patient %in% cellularity_data2$Patient,]


#Stroma-rich versus not stroma-rich
cellularity_data2$sr = ''
sr = cellularity_data2[cellularity_data2$Patient %in% subtypes5$Patient[subtypes5$Consensus!='Stroma-rich' & (subtypes5$Consensus.post=='Stroma-rich')],]
nsr = cellularity_data2[!cellularity_data2$Patient %in% sr$Patient,]

#Supp. Fig. 1A
ggpaired(cellularity_data2, x = "Timepoint", y = "Cellularity",
         color = "darkgray",line.color = "black", line.size = 0.4,
         point.size = 4,fill="Timepoint")+
  stat_compare_means(paired = TRUE,comparisons = list(c('Pre-Treatment','Post-Treatment')),
                     aes(label = ..p.format..),
                     label.x = 1.5,size=5)+theme(legend.position='')+xlab('')+ylab('Tumor Cellularity')+
  scale_fill_manual(values=c('darkgreen','maroon'))+
  ggtitle('non-pCR Patients')

#Supplementary Figure 1B
ggpaired(sr, x = "Timepoint", y = "Cellularity",
         color = "darkgray",line.color = "black", line.size = 0.4,
         point.size = 4,fill="Timepoint")+
  stat_compare_means(paired = TRUE,comparisons = list(c('Pre-Treatment','Post-Treatment')),
                     aes(label = ..p.format..),
                     label.x = 1.5,size=5)+theme(legend.position='')+xlab('')+ylab('Tumor Cellularity')+
  scale_fill_manual(values=c('darkgreen','maroon'))+
  ggtitle('Change to Stroma-rich')

#Supplementary Figure 1C
ggpaired(nsr, x = "Timepoint", y = "Cellularity",
         color = "darkgray",line.color = "black", line.size = 0.4,
         point.size = 4,fill="Timepoint")+
  stat_compare_means(paired = TRUE,comparisons = list(c('Pre-Treatment','Post-Treatment')),
                     aes(label = ..p.format..),
                     label.x = 1.5,size=5)+theme(legend.position='')+xlab('')+ylab('Tumor Cellularity')+
  scale_fill_manual(values=c('darkgreen','maroon'))+
  ggtitle('No change to Stroma-rich')


#Pre-treatment consensus subtype
cellularity_data2 = cellularity_data2[cellularity_data2$Timepoint=='Pre-Treatment',]
cellularity_data3 = full_join(cellularity_data2,subtypes5,by="Patient")
cellularity_data3 = cellularity_data3[!is.na(cellularity_data3$Consensus),]

#Supplementary Figure 1D
ggplot(cellularity_data3[1:11,], aes(x = Consensus, y = Cellularity,
                                     fill = Consensus), 
       palette = "jco",point.size = 4,alpha=0.6)+geom_boxplot(outlier.shape='')+geom_jitter(size=4,color='black',alpha=0.6)+
  stat_compare_means(paired = TRUE,label.y=1.2)+theme(legend.position='')+xlab('')+ylab('Tumor Cellularity')+
  ggtitle('Pre-treatment Consensus subtype')+scale_fill_manual(values=c("#FF1D1E","#20FF78","#237BFE","#D2FF1F"))+theme_bw()+theme(legend.position='')




#Supp. Fig. 1E


subswitch = read.csv('dsp_path.csv')

ss2 = data.frame(c(subswitch$pre,subswitch$post),c(rep('Pre',5),rep('Post',5)),c(subswitch$pre_sub,subswitch$post_sub),x=as.character(c(1:5,1:5)))
colnames(ss2) = c('percent','timepoint','subtype','name')
ss2$switch= rep(c('X','Y','Y','Y','X'),2)
ss2$timepoint=factor(ss2$timepoint,levels=c('Pre','Post'))
ss2$Patient = rep(c(110,112,121,124,131),2)

ggplot(ss2,aes(x=timepoint,y=percent,group=name))+
  geom_line(aes(color=switch),size=3)+geom_point(aes(color=subtype,size=4))+
  facet_wrap(~name)+
  scale_size(guide='none')+
  scale_colour_manual(values=c("#FF1D1E","#20FF78","#D2FF1F",'gray','black'),
                      labels=c('Ba/Sq','LumP','Stroma-rich','No subtype switch','Subtype switch'),
                      name='')+
  theme_bw()+theme(panel.grid.major.x = element_blank(),strip.background = element_blank(),strip.text=element_blank())+
  ylab('% Tumor Purity')+xlab('Timepoint (pre-vs. post-treatment)')+ylim(c(0,100))+
  theme(axis.title=element_text(face='bold'))


#Supp. Fig. 1F


tmb = read.csv('LCCC1520_TMB.csv')
tmb = tmb[-c(17,31),] #remove old samples with poor QC that have been re-sequenced
tmb$Patient = substr(tmb$Sample_ID,1,3)
tmbpre = tmb[substr(tmb$Sample_ID,6,6)=='r',] #pre-treatment TMB
tmbpost = tmb[substr(tmb$Sample_ID,6,6)=='o',] #post-treatment TMB


#only including samples with matched pre and post
tmb_pre_post = inner_join(tmbpre,tmbpost,by="Patient") #combine pre and post,
tmb_pre_post = tmb_pre_post[!(tmb_pre_post$Patient %in% as.character(clin$ID[clin$complete_response=='Yes'])),]
colnames(tmb_pre_post) = c('Sample_pre','TMB_pre','Patient','Sample_post','TMB_post')

ss2$Patient = as.character(ss2$Patient)
ss2$Timepoint='Pre-Treatment'
ss2$Timepoint[ss2$timepoint=='Post']='Post-Treatment'


ss2_pre = ss2[ss2$timepoint=='Pre',]
ss2_post = ss2[ss2$timepoint=='Post',]

ss2_pre_tmb = na.omit(full_join(ss2_pre,tmbpre,by='Patient'))
ss2_post_tmb = na.omit(full_join(ss2_post,tmbpost,by='Patient'))

ss2_pp = rbind(ss2_pre_tmb,ss2_post_tmb)

ggplot(ss2_pp,aes(x=percent,y=TMB,col=timepoint))+geom_point(size=4,alpha=0.6)+
  geom_smooth(method='lm',aes(x=percent,y=TMB,group=''),col='blue',alpha=0)+stat_cor(aes(x=percent,y=TMB,group=''),col='blue',
                                                                                     label.y=20)+
  scale_color_manual(values=c('darkgreen','maroon'),name='Timepoint',labels=c('Pre-treatment','Post-treatment'))+
  theme_bw()+xlab('% Tumor purity') + ylab('TMB')+theme_bw()+theme(panel.grid=element_blank(),axis.title=element_text(face='bold'))+ylim(0,40)+xlim(0,100)


#Supp. Fig. 1G

igs$time_patient = paste(igs$timepoint,igs$Patient,sep='')
ss2$time_patient = paste('p',substr(ss2$timepoint,2,nchar(as.character(ss2$timepoint))),ss2$Patient,sep='')
igsp = full_join(igs,ss2,by='time_patient')

ggplot(igsp,aes(percent,Bindea_CD8_T_cells))+geom_point(size=4,col='darkblue',alpha=0.6)+
  geom_smooth(method='lm',alpha=0,col='darkblue')+stat_cor()+
  theme_bw()+theme(panel.grid=element_blank(),axis.title=element_text(face='bold'))+
  xlab('% Tumor purity')+ylab('Bindea CD8 T cell signature')

#Supp. Fig. 1H

ggplot(igsp,aes(percent,Ayers_IFNG))+geom_point(size=4,col='darkblue',alpha=0.6)+
  geom_smooth(method='lm',alpha=0,col='darkblue')+stat_cor()+
  theme_bw()+theme(panel.grid=element_blank(),axis.title=element_text(face='bold'))+
  xlab('% Tumor purity')+ylab('Ayers IFNG signature')

#Supp. Fig. 1I

ggplot(igsp,aes(percent,IL_8))+geom_point(size=4,col='darkblue',alpha=0.6)+
  geom_smooth(method='lm',alpha=0,col='darkblue')+stat_cor()+
  theme_bw()+theme(panel.grid=element_blank(),axis.title=element_text(face='bold'))+
  xlab('% Tumor purity')+ylab('IL-8 signature')

#Supp. Fig. 1J

clinical$ID = as.character(clinical$ID)
subtypes[subtypes$Patient %in% subtypes$Patient[duplicated(subtypes$Patient)],]
all_post = unique(subtypes$Patient[subtypes$Patient %in% subtypes$Patient[duplicated(subtypes$Patient)]])
no_stroma_switch=c('110','115','117','120','131','137','143','144')

maf1520_df=data.frame(maf1520_pre@variants.per.sample$Variants,substr(maf1520_pre@clinical.data$Tumor_Sample_Barcode,1,3))
colnames(maf1520_df)=c('mutation_count','ID')
maf1520_df$timepoint='pre'
maf1520_df2 = data.frame(maf1520_post@variants.per.sample$Variants,substr(maf1520_post@clinical.data$Tumor_Sample_Barcode,1,3))
colnames(maf1520_df2)=c('mutation_count','ID')
maf1520_df2$timepoint='post'

maf1520_df3 = rbind(maf1520_df,maf1520_df2)
maf1520_df3$Patient=maf1520_df3$ID

maf1520_df5=full_join(maf1520_df3,clinical)
maf1520_df5$response = 'PR'
maf1520_df5$response[maf1520_df5$Pathologic_Responder=='No']='NR'

maf1520_df5 = maf1520_df5[maf1520_df5$ID %in% all_post,]
maf1520_df5$stroma='Switch to Stroma-rich'
maf1520_df5$stroma[maf1520_df5$ID %in% no_stroma_switch] = 'Other'
maf1520_df6 = maf1520_df5[!is.na(maf1520_df5$timepoint)&maf1520_df5$timepoint=='post',]


ggplot(maf1520_df6,aes(stroma,mutation_count,fill=stroma))+geom_boxplot(outlier.shape='',alpha=0.2,width=0.5)+
  geom_jitter(width=0.2,size=4,alpha=0.6,aes(fill=stroma),pch=21,col='black')+stat_compare_means()+
  theme_bw()+theme(panel.grid.major.x=element_blank())+ylab('Post-treatment mutation count')+
  xlab('')+scale_fill_manual(values=c('gray','darkred'),name='')+theme(legend.position = '')+
  theme(axis.title = element_text(face='bold'))



#Supp. Fig. 1K

maf1520_df7 = maf1520_df6[maf1520_df6$Patient%in%ss2$Patient,]

ggplot(maf1520_df7,aes(stroma,mutation_count,fill=stroma))+geom_boxplot(outlier.shape='',alpha=0.2,width=0.5)+
  geom_jitter(width=0.2,size=4,alpha=0.6,aes(fill=stroma),pch=21,col='black')+stat_compare_means()+
  theme_bw()+theme(panel.grid.major.x=element_blank())+ylab('Post-treatment mutation count')+
  xlab('')+scale_fill_manual(values=c('gray','darkred'),name='')+theme(legend.position = '')+
  theme(axis.title = element_text(face='bold'))


#Supp. Fig. 1L


ss2_post$stroma = 'Switch to Stroma-rich'
ss2_post$stroma[ss2_post$Patient %in% no_stroma_switch]='Other'
ss2_post2 = inner_join(ss2_post,tmbpost,by='Patient')

ggplot(ss2_post2,aes(stroma,TMB,fill=stroma))+geom_boxplot(outlier.shape='',alpha=0.2,width=0.5)+
  geom_jitter(width=0.2,size=4,alpha=0.6,aes(fill=stroma),pch=21,col='black')+stat_compare_means()+
  theme_bw()+theme(panel.grid.major.x=element_blank())+ylab('Post-treatment mutation count')+
  xlab('')+scale_fill_manual(values=c('gray','darkred'),name='')+theme(legend.position = '')+
  theme(axis.title = element_text(face='bold'))


```


#Supp. Fig. 2

```{r}


cellularity_data = read.csv('ploidy.csv')
cellularity_data$Timepoint = substr(cellularity_data$Patient,1,2) == 'pr'
cellularity_data$Timepoint[cellularity_data$Timepoint==TRUE] = 'Pre-Treatment'
cellularity_data$Timepoint[cellularity_data$Timepoint==FALSE] = 'Post-Treatment'
cellularity_data$Timepoint = factor(cellularity_data$Timepoint,levels=c('Pre-Treatment','Post-Treatment'))
cellularity_data$patient = cellularity_data$Patient


subswitch = read.csv('dsp_path.csv')

ss2 = data.frame(c(subswitch$pre,subswitch$post),c(rep('Pre',5),rep('Post',5)),c(subswitch$pre_sub,subswitch$post_sub),x=as.character(c(1:5,1:5)))
colnames(ss2) = c('percent','timepoint','subtype','name')
ss2$switch= rep(c('X','Y','Y','Y','X'),2)
ss2$timepoint=factor(ss2$timepoint,levels=c('Pre','Post'))

ss3 = ss2
ss3 = ss3[ss3$timepoint=='Post',]
ss3$Cellularity=NA

ss3$Cellularity[2]=cellularity_data$Cellularity[cellularity_data$Patient=='pre112']-cellularity_data$Cellularity[cellularity_data$Patient=='post112']
ss3$Cellularity[3]=cellularity_data$Cellularity[cellularity_data$Patient=='pre121']-cellularity_data$Cellularity[cellularity_data$Patient=='post121']
ss3$Cellularity[4]=cellularity_data$Cellularity[cellularity_data$Patient=='pre124']-cellularity_data$Cellularity[cellularity_data$Patient=='post124']
ss3$Cellularity[5]=cellularity_data$Cellularity[cellularity_data$Patient=='pre131']-cellularity_data$Cellularity[cellularity_data$Patient=='post131']


#Supp. Fig. 2A
ggplot(ss3,aes(percent,Cellularity))+geom_point(size=4,color='darkblue',alpha=0.8)+stat_cor()+geom_smooth(method='lm',color='blue',alpha=0)+ylim(-0.5,0.2)+
  theme_bw()+theme(panel.grid=element_blank())+xlab('Post-treatment % tumor purity')+ylab('Change in cellularity, pre-to post-treatment')





tmbpre$patient = paste('pre',tmbpre$Patient,sep='')
tmbpost$patient = paste('post',tmbpost$Patient,sep='')
tpp = rbind(tmbpre,tmbpost)

cellularity_data2 = full_join(cellularity_data,tpp,by='patient')
cellularity_data2 = cellularity_data2[cellularity_data2$Response!='CR',]
cellularity_data2 = na.omit(cellularity_data2)

cellularity_df = data.frame(cellularity_data2$Patient.y,cellularity_data2$Cellularity,cellularity_data2$Timepoint,cellularity_data2$TMB)
colnames(cellularity_df)=c('Patient','Cellularity','Timepoint','TMB')

cellularity_df2 = full_join(cellularity_df[cellularity_df$Timepoint=='Post-Treatment',],
                            cellularity_df[cellularity_df$Timepoint=='Pre-Treatment',],by='Patient',relationship='many-to-many')
cellularity_df2 = cellularity_df2[!is.na(cellularity_df2$TMB.x)&!is.na(cellularity_df2$TMB.y)&!is.na(cellularity_df2$Cellularity.x)&!is.na(cellularity_df2$Cellularity.y),]
cellularity_df2$TMB.change = cellularity_df2$TMB.x-cellularity_df2$TMB.y
cellularity_df2$pTMB.change = (cellularity_df2$TMB.x-cellularity_df2$TMB.y)/cellularity_df2$TMB.y*100
cellularity_df2$Cellularity.change = cellularity_df2$Cellularity.x-cellularity_df2$Cellularity.y

#Supp. Fig. 2B

ggplot(cellularity_df2,aes(Cellularity.change,TMB.change))+geom_point(size=4,alpha=0.6,color='darkblue')+stat_cor()+geom_smooth(method='lm',color='blue',alpha=0)+
  theme_bw()+theme(panel.grid=element_blank())+xlab('Cellularity change, pre-vs. post-treatment')+
  ylab('TMB change, pre-vs. post-treatment')+theme(axis.title=element_text(face='bold'))

#Supp. Fig. 2C

ggplot(cellularity_df2,aes(Cellularity.change,pTMB.change))+geom_point(size=4,alpha=0.6,color='darkblue')+stat_cor()+geom_smooth(method='lm',color='blue',alpha=0)+
  theme_bw()+theme(panel.grid=element_blank())+xlab('Cellularity change, pre-vs. post-treatment')+
  ylab('% TMB change, pre-vs. post-treatment')+theme(axis.title=element_text(face='bold'))




maf1520_df=data.frame(maf1520_pre@variants.per.sample$Variants,substr(maf1520_pre@clinical.data$Tumor_Sample_Barcode,1,3))
colnames(maf1520_df)=c('mutation_count','ID')
maf1520_df$timepoint='pre'
maf1520_df2 = data.frame(maf1520_post@variants.per.sample$Variants,substr(maf1520_post@clinical.data$Tumor_Sample_Barcode,1,3))
colnames(maf1520_df2)=c('mutation_count','ID')
maf1520_df2$timepoint='post'

maf1520_df3 = rbind(maf1520_df,maf1520_df2)
maf1520_df3$ID=as.numeric(maf1520_df3$ID)
clinical$ID = as.numeric(clinical$Patient)
maf1520_df5=full_join(maf1520_df3,clinical)
maf1520_df5$response = 'PR'
maf1520_df5$response[maf1520_df5$Pathologic_Responder=='No']='NR'
maf1520_df6 = maf1520_df5[!is.na(maf1520_df5$timepoint)&maf1520_df5$timepoint=='post'&maf1520_df5$Patient%in%tmbpp_no_CR$Patient,]

#Supp. Fig. 2D

ggplot(maf1520_df6,aes(response,mutation_count,fill=response))+geom_boxplot(outlier.shape='',alpha=0.5,width=0.5)+
  geom_jitter(width=0.2,size=4,alpha=0.6,height=0)+stat_compare_means()+
  theme_bw()+theme(panel.grid.major.x=element_blank())+ylab('Post-treatment mutation count')+
  xlab('')+scale_fill_manual(values=c('gold','brown'),name='')+theme(legend.position = '')+
  theme(axis.title=element_text(face='bold'))


#Supp. Fig. 2E

#read in .maf file
maf1520 = read.maf(maf = 'lccc1520.somatic_filtered_merged.maf')

#protein-coding mutations only
maf1520 = subsetMaf(maf1520,query = "BIOTYPE=='protein_coding'")

#Cadabra indel quality >10.5, 
#Mutect2 indel quality >6.8 or SNV quality >9.2,
#Strelka2 indel quality >15.2 or SNV quality >19.7
maf1520 = subsetMaf(maf1520,query = "(CADABRA_QUAL>10.5)|
                 (MUTECT2_TLOD > 9.2) | 
                 (Variant_Type %in% c('INS','DEL') & MUTECT2_TLOD>6.8)|
                 (STRELKA2_SomaticEVS > 19.7) | 
                 (Variant_Type %in% c('INS','DEL') & STRELKA2_SomaticEVS>15.2)")

#Remaining variants required at least 5 supporting reads and a minimum read depth of 40,
#or 10 supporting reads and minimum read depth of 80 if MAF <5%
maf1520 = subsetMaf(maf1520,query = "((t_alt_count/(t_ref_count))>=0.05 &
                 t_alt_count>=5 & t_depth>=40)|
                 ((t_alt_count/(t_ref_count))<0.05 &
                 t_alt_count>=10 & t_depth>=80)")

#Variants with a MAF>5% in normal tissue were dropped...
maf1520 = subsetMaf(maf1520,query = "n_alt_count/(n_ref_count)<=0.05")

#...as were variants appearing at rates above 1% in any subpopulation in either
#GnomAD...
maf1520 = subsetMaf(maf1520,query = "gnomAD_AFR_AF<=0.01 | is.na(gnomAD_AFR_AF)")
maf1520 = subsetMaf(maf1520,query = "gnomAD_ASJ_AF<=0.01| is.na(gnomAD_ASJ_AF)")
maf1520 = subsetMaf(maf1520,query = "gnomAD_FIN_AF<=0.01| is.na(gnomAD_FIN_AF)")
maf1520 = subsetMaf(maf1520,query = "gnomAD_NFE_AF<=0.01| is.na(gnomAD_NFE_AF)")
maf1520 = subsetMaf(maf1520,query = "gnomAD_OTH_AF<=0.01| is.na(gnomAD_OTH_AF)")
maf1520 = subsetMaf(maf1520,query = "gnomAD_SAS_AF<=0.01| is.na(gnomAD_SAS_AF)")

#...or 1000 Genomes databases
maf1520 = subsetMaf(maf1520,query = "AFR_AF<=0.01| is.na(AFR_AF)")
maf1520 = subsetMaf(maf1520,query = "AMR_AF<=0.01| is.na(AMR_AF)")
maf1520 = subsetMaf(maf1520,query = "ASN_AF<=0.01| is.na(ASN_AF)")
maf1520 = subsetMaf(maf1520,query = "EAS_AF<=0.01| is.na(EAS_AF)")
maf1520 = subsetMaf(maf1520,query = "EUR_AF<=0.01| is.na(EUR_AF)")
maf1520 = subsetMaf(maf1520,query = "SAS_AF<=0.01| is.na(SAS_AF)")
maf1520 = subsetMaf(maf1520,query = "AA_AF<=0.01| is.na(AA_AF)")
maf1520 = subsetMaf(maf1520,query = "EA_AF<=0.01| is.na(EA_AF)")


#Look at all mutations first, regardless of MAF


#remove old samples with poor QC that have been re-sequenced
maf1520 = subsetMaf(maf1520,tsb = names(table(maf1520@data$Tumor_Sample_Barcode))[-c(17,31)])

#Label pre and post timepoints
maf1520@clinical.data$Timepoint = substr(maf1520@clinical.data$Tumor_Sample_Barcode,5,7)
maf1520@clinical.data$Timepoint[maf1520@clinical.data$Timepoint=='pre']='Pre-Treatment'
maf1520@clinical.data$Timepoint[maf1520@clinical.data$Timepoint=='pos']='Post-Treatment'
maf1520@clinical.data$Timepoint[c(23,29,42,47,37,39,44,45,49,50)] = 'Pre-Treatment'
maf1520@clinical.data$Timepoint[c(15,21,24,31)] = 'Post-Treatment'

#All pre-treatment samples
maf1520_pre = maf1520_pre = subsetMaf(maf1520,tsb = maf1520@clinical.data$Tumor_Sample_Barcode[maf1520@clinical.data$Timepoint=='Pre-Treatment'])

maf1520@clinical.data$Patient= substr(maf1520@clinical.data$Tumor_Sample_Barcode,1,3)
#Post-treatment non-pCR samples


maf1520_post = subsetMaf(maf1520,tsb = maf1520@clinical.data$Tumor_Sample_Barcode[maf1520@clinical.data$Timepoint=='Post-Treatment' & 
                                                                                    !(maf1520@clinical.data$Patient %in% clin$Patient[clin$complete_response=='Yes'])])



maf1520_pre_nocr = subsetMaf(maf1520,tsb = names(table(maf1520@data$Tumor_Sample_Barcode))[maf1520@clinical.data$Timepoint=='Pre-Treatment' & 
                                                                                             !(maf1520@clinical.data$Patient %in% clinical$Patient[clinical$complete_response=='Yes'])])

maf1520_post2 = subsetMaf(maf1520_post,tsb = names(table(maf1520_post@data$Tumor_Sample_Barcode))[maf1520_post@clinical.data$Patient %in% maf1520_pre_nocr@clinical.data$Patient])

maf1520_pre2 = subsetMaf(maf1520_pre_nocr,tsb = names(table(maf1520_pre_nocr@data$Tumor_Sample_Barcode))[maf1520_pre_nocr@clinical.data$Patient %in% maf1520_post2@clinical.data$Patient])

maf1520_post2@clinical.data$Patient
maf1520_pre2@clinical.data$Patient


both=maf1520_pre2@gene.summary$Hugo_Symbol[maf1520_pre2@gene.summary$Hugo_Symbol%in%maf1520_post2@gene.summary$Hugo_Symbol]

maf1520_pre3 = as.data.frame(maf1520_pre2@data)
maf1520_post3 = as.data.frame(maf1520_post2@data)

maf1520_pre3$Patient = substr(maf1520_pre3$Tumor_Sample_Barcode,1,3)
maf1520_post3$Patient = substr(maf1520_post3$Tumor_Sample_Barcode,1,3)

maf1520_pre3$StartEnd = paste(maf1520_pre3$Start_Position,maf1520_pre3$End_Position,maf1520_pre3$Amino_acids,maf1520_pre3$Patient, sep='_')
maf1520_post3$StartEnd = paste(maf1520_post3$Start_Position,maf1520_post3$End_Position,maf1520_post3$Amino_acids,maf1520_post3$Patient,sep='_')

maf1520_pre3=maf1520_pre3[maf1520_pre3$StartEnd %in% maf1520_post3$StartEnd,]
maf1520_post3=maf1520_post3[maf1520_post3$StartEnd %in% maf1520_pre3$StartEnd,]

maf1520_pre3 = maf1520_pre3[!duplicated(maf1520_pre3$StartEnd),]
maf1520_post3 = maf1520_post3[!duplicated(maf1520_post3$StartEnd),]
maf1520_pre3=maf1520_pre3[order(maf1520_pre3$StartEnd),]
maf1520_post3=maf1520_post3[order(maf1520_post3$StartEnd),]

maf1520_pre3$StartEnd==maf1520_post3$StartEnd

cov = data.frame(c(maf1520_pre3$t_depth,
                   maf1520_post3$t_depth),c(rep('Pre-Treatment',nrow(maf1520_pre3)),
                                            rep('Post-Treatment',nrow(maf1520_post3))),
                 c(maf1520_pre3$StartEnd,maf1520_post3$StartEnd))


colnames(cov)=c('val','Timepoint','name')
cov$Timepoint=factor(cov$Timepoint,levels=c('Pre-Treatment','Post-Treatment'))

ggplot(cov,aes(Timepoint,val))+geom_boxplot(aes(fill=Timepoint),width=0.5,alpha=0.6)+geom_line(aes(group=name),alpha=0.1,col='darkblue')+
  stat_compare_means(paired=T,method='wilcox')+scale_y_log10()+theme_bw()+theme(panel.grid.major.x=element_blank(),
                                                                                panel.grid.minor.x=element_blank())+
  scale_fill_manual(values=c('darkgreen','orchid'))+theme(legend.position='')+
  ylab('Tumor Read Depth at Shared Mutational Loci')+
  theme(axis.title=element_text(face='bold'))



#Supp. Fig. 2F: PBMC BCR and TCR diversity metrics

#Read in data

clinical = read.csv('Clinical1520.csv')
clinical$Patient = as.character(clinical$ID)
rec = read.csv('receptor.csv')
rec_id = read.csv('receptor_id.csv')

#Select only the PBMC samples
rec_id = rec_id[!(substr(rec_id$Filename,1,4)%in%c('1520','LCCC')),]

#Define Patient and Sample
rec_id$Patient = substr(rec_id$Filename,1,3)
colnames(rec_id)[1] = 'Sample'

#Combine receptor and ID files
ri = right_join(rec,rec_id,by="Sample")

#Select only samples with a timepoint listed
ri2 = ri[!is.na(ri$Timepoint),]

#Combine receptor diversity metrics with clinical data
clin_ri = right_join(clinical,ri2,by="Patient")

#select pre (course1) and post samples
c1 = clin_ri[clin_ri$Timepoint=='course1',]
c2 = clin_ri[clin_ri$Timepoint=='post',]


#Only matched pairs
c1 = c1[c1$Patient %in% c2$Patient,]
c2 = c2[c2$Patient %in% c1$Patient,]
c1 = c1[!duplicated(c1$Patient),]
c2 = c2[!duplicated(c2$Patient),]

#Only relevant metrics
c1 = c1[,c(20,24,25,29,30,34,35,39,40,44)]
c2 = c2[,c(20,24,25,29,30,34,35,39,40,44)]

#Calculate differential change by metric
rec_df = data.frame(matrix(nrow=10,ncol=3))
colnames(rec_df) = c('pop','diff','p')
rec_df$pop = colnames(c1)[1:10]

for (i in 1:10){
  a = na.omit(c1[,i])
  b = na.omit(c2[,i])
  rec_df$diff[i] = mean(na.omit((b-a)))/mean(na.omit(a))*100
  rec_df$p[i] = wilcox.test(a,b,paired=TRUE)$p.value
}
rec_df$padj = p.adjust(rec_df$p,method="BH")

#remove NS outlier
rec_df = rec_df[rec_df$diff>-200,]

rec_df$col = 1*(rec_df$padj<0.05) + 2*(rec_df$diff>0)
rec_df$col[rec_df$col==0] = 'gray'
rec_df$col[rec_df$col==1] = 'darkblue'
rec_df$col[rec_df$col==2] = 'gray'
rec_df$col[rec_df$col==3] = 'darkred'
rec_df$name = 1*(rec_df$padj<0.05) + 2*(rec_df$diff>0)
rec_df$name[rec_df$name==0] = 'NS'
rec_df$name[rec_df$name==1] = 'Down, sig.'
rec_df$name[rec_df$name==2] = 'NS'
rec_df$name[rec_df$name==3] = 'Up, sig.'

#Set labels of points
rec_df$igs_short = rec_df$pop
rec_df$igs_short[rec_df$padj>0.05] = ''

ggplot(rec_df,aes(y = -log10(p),x=diff,col=col,label=pop))+geom_point(aes(color=col),size=4)+
  scale_colour_identity("",labels=rec_df$name,breaks=rec_df$col,guide="legend")+
  geom_text_repel(color='black')+
  ylab('-log10 paired Wilcoxon p-value')+xlab('% increase pre-to post-treatment')+
  geom_text_repel(aes(label=igs_short),show.legend=FALSE)+
  # geom_text_repel(aes(label=pop),col='black')+
  theme_bw()+ggtitle('PBMC TCR and BCR Diversity')+theme(plot.title = element_text(face="bold"),
                                                         axis.title.y = element_text(face="bold"),
                                                         axis.title.x = element_text(face="bold"),
                                                         panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
                                                         panel.background = element_blank(), axis.line = element_line(colour = "black"))



cg_pre_nocr = clin_gene[clin_gene$Timepoint=='pre' & clin_gene$complete_response=='No',]
cg_pre_nocr$tmbinc='No'
cg_pre_nocr$tmbinc[cg_pre_nocr$ID %in% c(112,137)]='Yes'

#Supp. Fig. 2G

ggplot(cg_pre_nocr,aes(tmbinc,CD274.29126,fill=tmbinc,col=tmbinc))+geom_boxplot(outlier.shape=NA,alpha=0.2,width=0.5)+                                                                                            
  scale_fill_manual(values=c('gray','darkred'))+theme(legend.position='')+
  scale_color_manual(values=c('gray','darkred'))+
  xlab('TMB increase, pre-to post-treatment')+
  ylab('Log2 PD-L1 expression, pre-treatment')+
  stat_compare_means()+
  geom_jitter(alpha=0.5,size=4,height=0,width=0.2,aes(col=tmbinc))+
  theme(axis.title = element_text(face="bold"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))



#Supp. Fig. 2H

ggplot(cg_pre_nocr,aes(tmbinc,TIGIT.201633,fill=tmbinc,col=tmbinc))+geom_boxplot(outlier.shape=NA,alpha=0.2,width=0.5)+                                                                                            
  scale_fill_manual(values=c('gray','darkred'))+theme(legend.position='')+
  scale_color_manual(values=c('gray','darkred'))+
  xlab('TMB increase, pre-to post-treatment')+
  ylab('Log2 TIGIT expression, pre-treatment')+
  stat_compare_means()+
  geom_jitter(alpha=0.5,size=4,height=0,width=0.2,aes(col=tmbinc))+
  theme(axis.title = element_text(face="bold"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))


#Supp. Fig. 2I


igs_pre$tmbinc='No'
igs_pre$tmbinc[igs_pre$Patient %in% c('112','137')]='Yes'
igs_pre2 = igs_pre[igs_pre$Patient %in% cg_pre_nocr$Patient,]

ggplot(igs_pre2,aes(tmbinc,Ayers_IFNG,fill=tmbinc,col=tmbinc))+geom_boxplot(outlier.shape=NA,alpha=0.2,width=0.5)+                                                                                            
  scale_fill_manual(values=c('gray','darkred'))+theme(legend.position='')+
  scale_color_manual(values=c('gray','darkred'))+
  xlab('TMB increase, pre-to post-treatment')+
  ylab('Pre-treatment Ayers IFNG signature')+
  stat_compare_means()+
  geom_jitter(alpha=0.5,size=4,height=0,width=0.2,aes(col=tmbinc))+
  theme(axis.title = element_text(face="bold"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))


```

#Supp. Fig. 3

```{r}


flow_live = read.csv('flow_live.csv')

flow_live$Value = as.numeric(gsub("[^0-9.-]", "", flow_live$Value))
flow_live = na.omit(flow_live)
flow_live$Timepoint[flow_live$Timepoint=='C1']='Pre-treatment'
flow_live$Timepoint[flow_live$Timepoint=='C2']='Cycle 2'
flow_live$Timepoint=factor(flow_live$Timepoint,levels=c('Pre-treatment','Cycle 2'))

#Supp. Fig. 3D

ggplot(flow_live,aes(x=Population,y=Value))+geom_boxplot(fill='darkblue',alpha=0.2)+
  geom_jitter(width=0.2,size=3,alpha=0.5,col='darkblue')+facet_wrap(~Timepoint)+
  scale_y_continuous(trans='log2',breaks=c(0.01,0.1,1,10))+
  theme_bw()+theme(panel.grid=element_blank())+theme(axis.text.x=element_text(angle=90))+
  xlab('')+ylab('Percent of Live Cells')+
  theme(axis.title=element_text(face='bold'))






pre_c2_change = data.frame(matrix(nrow=55,ncol=5))
colnames(pre_c2_change) = c('pop','pre','c2','diff','p')
pre_c2_change$pop = colnames(fcc2)[c(1:55)]
prec2 = full_join(fcc2,fcpre,by="Patient")


for (j in c(1:55)){
  pre3  = prec2[!is.na(prec2[,j]) & !is.na(prec2[,j+ncol(fcc2)]),]
  df = data.frame(as.numeric(pre3[,j]),as.numeric(pre3[,j+ncol(fcc2)]))
  colnames(df) = c('c2','pre')
  pre_c2_change$pre[j] = mean(df$pre)
  pre_c2_change$c2[j] = mean(df$c2)
  pre_c2_change$diff[j] = mean(df$c2-df$pre)/mean(df$pre)*100
  pre_c2_change$p[j] = wilcox.test(df$pre,df$c2,paired=T)$p.value
}
pre_c2_change$padj = (p.adjust(pre_c2_change$p,method='BH'))
pre_c2_change$col = 1*(pre_c2_change$padj<0.05) + 2*(pre_c2_change$diff>0)
pre_c2_change$col[pre_c2_change$col==0] = 'gray'
pre_c2_change$col[pre_c2_change$col==1] = 'darkblue'
pre_c2_change$col[pre_c2_change$col==2] = 'gray'
pre_c2_change$col[pre_c2_change$col==3] = 'darkred'
pre_c2_change$name = 1*(pre_c2_change$padj<0.05) + 2*(pre_c2_change$diff>0)
pre_c2_change$name[pre_c2_change$name==0] = 'NS'
pre_c2_change$name[pre_c2_change$name==1] = 'Down, sig.'
pre_c2_change$name[pre_c2_change$name==2] = 'NS'
pre_c2_change$name[pre_c2_change$name==3] = 'Up, sig.'

pre_c2_change$igs_short = pre_c2_change$pop
pre_c2_change$igs_short[pre_c2_change$padj>0.05] = ''





fcpreb = fcpre[,colnames(fcpre) %in% c('Patient',pre_c2_change$igs_short[c(4,19,23,28,32,39,41,42,46,50)])]
fcc2b = fcc2[,colnames(fcc2) %in% c('Patient',pre_c2_change$igs_short[c(4,19,23,28,32,39,41,42,46,50)])]


fc=inner_join(fcpreb,fcc2b,by='Patient')
fc2 = data.frame(matrix(ncol=10,nrow=nrow(fc)))
colnames(fc2) = c('CD19+ CD10+ Transitional B cells','PMN_MDSC: CD14- CD15+ CD11b+',
                  'eMDSC: Lin- HLADR- CD33+ CD11b+',
                  'CD45RA+ CD4+ PD1+','CD45RA+ CD8+ PD1+','CD45RA- CD8+ PD1+',
                  'CD45RA- CD4+ PD1+','CD45RA- CD8+ CD39+',
                  'CD45RA+ CD4+ Helios+','CD45RA- CD4+ TIGIT+ CD39+')

for (i in 1:ncol(fc2)){
  fc2[,i] = (fc[,i+11]-fc[,i])/fc[,i]*100
}

cormat <- round(cor(fc2,use='pairwise.complete.obs'),2)
melted_cormat <- melt(cormat)
head(melted_cormat)

#Supp. Fig. 3E

ggplot(data = melted_cormat, aes(x=Var1, y=Var2, fill=value)) + 
  geom_tile()+scale_fill_gradient2(low='blue',high='red',mid='white',name='Pearson R')+
  ylab('')+xlab('')+
  theme_bw()+theme(panel.grid=element_blank())+
  theme(axis.text.x=element_text(angle=90))



```


#Supp. Fig. 4

```{r}

#Read in data

post111 = read.delim('IMGF_1520-111_post.lens_report.txt')
pre111 = read.delim('IMGF_1520-111_pre.lens_report.txt')

post112 = read.delim('IMGF_1520-112_post.lens_report.txt')
pre112 = read.delim('IMGF_1520-112_pre.lens_report.txt')

pre113 = read.delim('IMGF_1520-113_pre.lens_report.txt')

pre114 = read.delim('IMGF_1520-114_pre.lens_report.txt')

post115 = read.delim('IMGF_1520-115_post.lens_report.txt')
pre115 = read.delim('IMGF_1520-115_pre.lens_report.txt')

post116 = read.delim('IMGF_1520-116_post.lens_report.txt')

post117 = read.delim('IMGF_1520-117_post.lens_report.txt')
pre117 = read.delim('IMGF_1520-117_pre.lens_report.txt')

pre119 = read.delim('IMGF_1520-119_pre.lens_report.txt')

post120 = read.delim('IMGF_1520-120_post.lens_report.txt')
pre120 = read.delim('IMGF_1520-120_pre.lens_report.txt')

post121 = read.delim('IMGF_1520-121_post.lens_report.txt')
pre121 = read.delim('IMGF_1520-121_pre.lens_report.txt')

post122 = read.delim('IMGF_1520-122_post.lens_report.txt')
pre122 = read.delim('IMGF_1520-122_pre.lens_report.txt')

post123 = read.delim('IMGF_1520-123_post.lens_report.txt')
pre123 = read.delim('IMGF_1520-123_pre.lens_report.txt')

post124 = read.delim('IMGF_1520-124_post.lens_report.txt')
pre124 = read.delim('IMGF_1520-124_pre.lens_report.txt')

pre125 = read.delim('IMGF_1520-125_pre.lens_report.txt')

pre126 = read.delim('IMGF_1520-126_pre.lens_report.txt')

pre127 = read.delim('IMGF_1520-127_pre.lens_report.txt')

pre128 = read.delim('IMGF_1520-128_pre.lens_report.txt')

pre130 = read.delim('IMGF_1520-130_pre.lens_report.txt')

post131 = read.delim('IMGF_1520-131_post.lens_report.txt')
pre131 = read.delim('IMGF_1520-131_pre.lens_report.txt')

pre133 = read.delim('IMGF_1520-133_pre.lens_report.txt')

pre134 = read.delim('IMGF_1520-134_pre.lens_report.txt')

pre136 = read.delim('IMGF_1520-136_pre.lens_report.txt')

pre137 = read.delim('IMGF_1520-137_pre.lens_report.txt')

pre138 = read.delim('IMGF_1520-138_pre.lens_report.txt')

pre139 = read.delim('IMGF_1520-139_pre.lens_report.txt')

post140 = read.delim('IMGF_1520-140_post.lens_report.txt')
pre140 = read.delim('IMGF_1520-140_pre.lens_report.txt')

post143 = read.delim('IMGF_1520-143_post.lens_report.txt')

post144 = read.delim('IMGF_1520-144_post.lens_report.txt')
colnames(pre111)

#Combine into lists, pre and post

pre_list = list(pre111,pre112,pre113,pre114,pre115,pre117,pre119,pre120,
                pre121,pre122,pre123,pre124,pre125,pre126,pre127,pre128,
                pre130,pre131,pre133,pre134,pre136,pre137,pre138,
                pre139,pre140)

names_pre = as.vector(c('pre111','pre112','pre113','pre114','pre115','pre117','pre119','pre120',
                        'pre121','pre122','pre123','pre124','pre125','pre126','pre127',
                        'pre128',
                        'pre130','pre131','pre133','pre134','pre136','pre137','pre138',
                        'pre139','pre140'))

post_list = list(post111,post112,post115,post116,post117,post120,post121,post123,post124,post131,post140,
                 post143,post144)


names_post = as.vector(c('post111','post112','post115','post116','post117',
                         'post120','post121','post123','post124','post131','post140',
                         'post143','post144'))


#Select non-duplicated antigens

for (i in 1:length(pre_list)){
  df= data.frame(pre_list[i])
  df$patient = names_pre[i]
  pre_list[i] = list(df[!duplicated(df$peptide),])
}


for (i in 1:length(post_list)){
  df= data.frame(post_list[i])
  df$patient = names_post[i]
  post_list[i] = list(df[!duplicated(df$peptide),])
}


#Reformat as data frames
antigens_pre = ldply(pre, data.frame)
antigens_post = ldply(post, data.frame)


#Select only antigens with lower than 500 BA and greater than 5 reads per peptide
antigens_pre = antigens_pre[antigens_pre$binding_affinity<500 & antigens_pre$reads_with_peptide>5,]
antigens_post = antigens_post[antigens_post$binding_affinity<500 & antigens_post$reads_with_peptide>5,]


#Make a table of antigen counts
tab_antigens = as.matrix(table(antigens_pre$patient,antigens_pre$antigen_source))
order_names = order(-rowSums(tab_antigens))


#Convert into a data frame
df_antigens = data.frame(table(antigens_pre$patient,antigens_pre$antigen_source))
df_antigens$Freq = as.numeric(df_antigens$Freq)
df_antigens$Var1 = factor(df_antigens$Var1,levels=unique(df_antigens$Var1)[order_names])

df_antigens$Antigen_Source = as.factor(df_antigens$Var2)

#Divide into self (CTA) and non-self antigens
df_self = df_antigens[df_antigens$Var2 == 'Self-Antigen',]
df_other = df_antigens[df_antigens$Var2 != 'Self-Antigen',]

df_other$Antigen_Source = factor(df_other$Antigen_Source,levels=c('InDel','SpliceVariant','SNV','ERV'))



df_self$ID = as.numeric(substr(df_self$Var1,4,6))
df_self = full_join(df_self,clin,by='ID')
df_self = df_self[!is.na(df_self$Var1),]
df_self = df_self[order(df_self$complete_response=='No',df_self$Pathologic_Responder=='No',-df_self$Freq),]
df_self$Var1=factor(df_self$Var1,levels=df_self$Var1)
order_names = df_self$Var1

#Supp. Fig. 4A

ggplot(data = df_self, aes(x = Var1, y = Freq, fill = Antigen_Source)) + 
  geom_bar(stat='identity')+xlab('')+ylab('Count')+theme_bw()+
  theme(axis.text.x=element_blank(),axis.ticks.x=element_blank(),panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  scale_fill_manual(values=c('#87E911'),name='Antigen source')+
  theme(axis.title=element_text(face='bold'))



df_other$ID = as.numeric(substr(df_other$Var1,4,6))
df_other = full_join(df_other,clin,by='ID')
df_other = df_other[!is.na(df_other$Var1),]
df_other$Var1=factor(df_other$Var1,levels=order_names)
df_other$Antigen_Source=factor(df_other$Antigen_Source,levels=c('ERV','InDel','SNV','SpliceVariant'))


ggplot(data = df_other, aes(x = Var1, y = Freq, fill = Antigen_Source)) + 
  geom_bar(stat='identity')+xlab('')+ylab('Count')+theme_bw()+
  theme(axis.text.x=element_blank(),axis.ticks.x=element_blank(),panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  scale_fill_manual(values=c('#F2CA19','#0057E9',
                             '#FF00BD',
                             '#8931EF'),name='Antigen source')+
  theme(axis.title=element_text(face='bold'))


#Read in TMB
tmb = read.csv('LCCC1520_TMB.csv')

#Remove old reads
tmb = tmb[-c(17,31),]

#Define patient and timepoint
tmb$Patient = substr(tmb$Sample_ID,1,3)
tmb$Timepoint = substr(tmb$Sample_ID,5,7)

#Only pre-treatment samples
tmb_pre = tmb[tmb$Timepoint=='pre',]
tmb_pre$Patient = paste('pre',tmb_pre$Patient,sep='')

tmb2 = tmb_pre[tmb_pre$Patient %in% order_names,]
tmb2$Patient = factor(tmb2$Patient,levels = order_names)


ggplot(data = tmb2, aes(x = Patient, y = TMB)) + 
  geom_bar(stat='identity')+xlab('')+ylab('TMB')+theme_bw()+
  theme(axis.text.x=element_blank(),axis.ticks.x=element_blank(),panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  scale_fill_manual(values='gray')


df_self$response = as.character(1*(df_self$Pathologic_Responder=='Yes')+2*(df_self$complete_response=='Yes'))
ggplot(df_self,aes(x=Var1,y=1,fill=response))+geom_tile()+theme_bw()+
  scale_fill_manual(values=c('brown','gold','orange'),name='',labels=c('NR','PR','CR'))+
  theme(axis.text = element_blank(),axis.ticks=element_blank())+ylab('')+xlab('')+theme(panel.grid=element_blank())





antigens_pre = ldply(pre, data.frame)
antigens_post = ldply(post, data.frame)

#Define Patient
antigens_pre$Patient = substr(antigens_pre$patient,4,6)
antigens_post$Patient = substr(antigens_post$patient,5,7)

#Join with clinical data
antigens_pre_clin= full_join(antigens_pre,clin,by='Patient')


#Select TESLA criteria antigens
antigens_pre_clin8 = antigens_pre_clin[antigens_pre_clin$tpm>33 & antigens_pre_clin$binding_affinity<34 & antigens_pre_clin$binding_stability>1.4,]
df_antigens_pre = data.matrix(table(antigens_pre_clin8$patient,antigens_pre_clin8$antigen_source))
table(antigens_pre_clin$patient,antigens_pre_clin$Pathologic_Responder)
df_antigens_pre = df_antigens_pre[rowSums(df_antigens_pre)!=0,]
df_antigens_pre = as.data.frame(df_antigens_pre)

df_antigens_pre2 = data.matrix(table(antigens_pre_clin$patient,antigens_pre_clin$antigen_source))
table(antigens_pre_clin$patient,antigens_pre_clin$Pathologic_Responder)
df_antigens_pre2 = as.data.frame(df_antigens_pre2)
df_antigens_pre2$Freq=0

#Fix label for patient 121
df_antigens_pre2$Var1 = '121'

#Combine data frames
df_antigens_pre = rbind(df_antigens_pre2,df_antigens_pre)

#Format data frame for plotting
df_antigens_pre$Var1 = as.factor(df_antigens_pre$Var1)
df_antigens_pre$Antigen_Source = factor(df_antigens_pre$Var2,levels=unique(antigens_pre_clin$antigen_source))
df_antigens_pre$Var1 = factor(df_antigens_pre$Var1, levels=c(unique(antigens_pre_clin8$patient[order(antigens_pre_clin8$patient)])[order(-table(antigens_pre_clin8$patient))]))
df_antigens_pre$Antigen_Source = factor(df_antigens_pre$Antigen_Source,levels=c('ERV','FusionEvent','InDel','Self-Antigen','SNV','SpliceVariant'))
df_antigens_pre= df_antigens_pre[df_antigens_pre$Freq!=0,]


df_tesla=full_join(df_self,df_antigens_pre,by='Var1')

df_tesla$tesla=df_tesla$Freq.y
df_tesla$tesla[is.na(df_tesla$tesla)]=0
df_tesla$response = as.character(1*(df_tesla$Pathologic_Responder=='Yes')+2*(df_tesla$complete_response=='Yes'))
df_tesla$Response = 'CR'
df_tesla$Response[df_tesla$response=='1']='PR'
df_tesla$Response[df_tesla$response=='0']='NR'
df_tesla$Response=factor(df_tesla$Response,levels=c('CR','PR','NR'))

df_tesla$tesla[df_tesla$Patient=='123']=3
df_tesla=df_tesla[!(df_tesla$Patient=='123'&df_tesla$Var2.y=='SNV'),]

ggplot(df_tesla,aes(Response,tesla,fill=Response))+geom_boxplot(outlier.shape='',alpha=0.2)+
  geom_jitter(size=4,alpha=0.5,width=0.2,height=0,aes(fill=Response),pch=21,col='black')+
  stat_compare_means(method='wilcox',comparisons=list(c('CR','NR'),c('CR','PR'),c('PR','NR')))+
  scale_fill_manual(values=c('orange','yellow','brown'),name='')+
  scale_color_manual(values=c('orange','yellow','brown'),guide=F)+theme_bw()+theme(panel.grid.major.x = element_blank())+
  ylab('Antigen count by Wells criteria')+
  theme(axis.text.x = element_blank(),axis.ticks.x=element_blank())+ylim(0,11)+xlab('')+theme(axis.title.y=element_text(face='bold'))



```



#Supp. Fig. 5

```{r}



#Supp. Fig. 5A

#Read in data
clin = read.csv('Clinical1520.csv')
clin$Patient = as.character(clin$ID)

tmb = read.csv('LCCC1520_TMB.csv')

#Remove old, poor QC reads
tmb = tmb[-c(17,31),]

#Define patient and timepoint
tmb$Patient = substr(tmb$Sample_ID,1,3)
tmb$Timepoint = substr(tmb$Sample_ID,5,7)

#Only pre-treatment samples
tmb_pre = tmb[tmb$Timepoint=='pre',]

#Combine TMB and clinical
clin_tmb = full_join(clin,tmb_pre,by="Patient")

#Add response categories
clin_tmb$Response = 'CR'
clin_tmb$Response[clin_tmb$complete_response=='No'] = 'PR'
clin_tmb$Response[clin_tmb$Pathologic_Responder=='No'] = 'NR'
clin_tmb$Response = factor(clin_tmb$Response,levels=c('CR','PR','NR'))


clin_tmb$adverse = clin_tmb$Reason_chemotherapy_ended=="Adverse events / Side effects (specify in Comments)"
clin_tmb$adverse[clin_tmb$Reason_chemotherapy_ended=='']=NA
clin_adv = clin_tmb[!is.na(clin_tmb$adverse),]
clin_adv$adverse2='None'
clin_adv$adverse2[clin_adv$adverse==TRUE]='Adverse Event'

clin_adv=clin_adv[clin_adv$Pathologic_Responder=='No',]

ggplot(clin_adv,aes(adverse2,TMB,fill=adverse2))+geom_boxplot(outlier.shape=NA,alpha=0.2,width=0.5)+
  stat_compare_means(method='wilcox',comparisons=list(c('Adverse Event','None')))+                                                                                              
  scale_fill_manual(values=c('magenta','navy'))+
  scale_color_manual(values=c('magenta','navy'))+xlab('')+theme(legend.position='')+
  geom_jitter(alpha=0.5,size=4,height=0,width=0.2,aes(color=adverse2))+
  theme(axis.title.y = element_text(face="bold"),
        axis.title.x = element_blank(),
        axis.text.x = element_text(face="bold",color="black"),
        title=element_text(face="bold"),
        panel.grid.major.x = element_blank() ,
        panel.grid.major.y = element_line( size=.1, color="gray" ) ,
        panel.grid.minor.x = element_blank() ,
        panel.grid.minor.y = element_line( size=.1, color="gray" ), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  ggtitle('Non-responders')



#Supp. Fig. 5B
igs_tmb_pre = full_join(igs_pre,tmb_pre,by='Patient')

ggplot(igs_tmb_pre,aes(TMB,Ayers_IFNG))+geom_point(size=4,alpha=0.8,col='darkblue')+stat_cor()+theme_bw()+
  geom_smooth(method='lm',col='blue')+
  theme(panel.grid=element_blank())+xlab('TMB')+
  ylab('Ayers IFNG signature')+theme(axis.title=element_text(face='bold'))


#Supp. Fig. 5C

clin_gene2 = full_join(clin_gene,igs_pre,by="Patient")
ggplot(clin_gene2,aes(CD274.29126,Ayers_IFNG))+geom_point(size=4,alpha=0.8,col='darkblue')+
  stat_cor(p.digits=2)+theme_bw()+
  geom_smooth(method='lm',col='blue')+
  theme(panel.grid=element_blank())+xlab('Log2 PD-L1 expression')+ylab('Ayers IFNG signature')+
  theme(axis.title=element_text(face='bold'))


#Supp. Fig. 5D

igs_pre2 = igs_pre[,-c(1,31,63:ncol(igs_pre))]
df_igs_pre = data.frame(matrix(nrow=60,ncol=3))
colnames(df_igs_pre) = c('sig','cor','p')
df_igs_pre$sig = colnames(igs_pre2)
for (i in 1:nrow(df_igs_pre)){
  df_igs_pre$cor[i] = cor(igs_pre2$Bindea_CD8_T_cells,igs_pre2[,i])
  df_igs_pre$p[i] = cor.test(igs_pre2$Bindea_CD8_T_cells,igs_pre2[,i])$p.value
}
df_igs_pre$padj = p.adjust(df_igs_pre$p,method='BH')
df_igs_pre$color='NS'
df_igs_pre$color[df_igs_pre$padj<0.05]='p<0.05'
df_igs_pre = df_igs_pre[df_igs_pre$sig!='Bindea_CD8_T_cells',]

df_igs_pre$sig[df_igs_pre$padj>0.05]=''
ggplot(df_igs_pre,aes(cor,-log10(padj),label=sig))+geom_point(aes(col=color),size=4,alpha=0.5)+scale_color_manual(values=c('gray','darkred'),name='')+
  theme_bw()+theme(panel.grid=element_blank())+ylab('-Log10 FDR-corrected p-value')+xlab('Pearson R')+geom_text_repel(max.overlaps=50)+
  theme(axis.title = element_text(face='bold'))


#Supp. Fig. 5E

#Read in data
clin_imv = read.csv('IMvigor210clinical.csv')

#Define response
clin_imv$Responder = 'NR'
clin_imv$Responder[clin_imv$binaryResponse=='CR/PR'] = 'Responder'
clin_imv$Responder[!(clin_imv$binaryResponse%in%c('CR/PR','SD/PD'))] = NA
fit_imvigor = survfit(Surv(os,censOS)~Responder+Sex,clin_imv)

ggsurvplot(fit_imvigor,pval=FALSE,size=1.5,censor.size=8,
           legend.title='',
           legend.labs = c("Female NR","Male NR","Female Responder","Male Responder"),
           xlab = 'Time (months)',
           palette='jco')







```


#Supp. Fig. 6

```{r}


#Read in data
clinical = read.csv('Clinical1520.csv')
B = read.csv('LCCC1520_B_cells.csv')
B = B[1:83,]
Myeloid = read.csv('LCCC1520_Myeloid_cells.csv')
Teff = read.csv('LCCC1520_Teff-reg.csv')

#Rename first column as "ID"
colnames(B)[1] = 'ID'
colnames(Myeloid)[1] = 'ID'
colnames(Teff)[1] = 'ID'

#Define Patient
B$Patient = substr(B$ID,1,3)
Myeloid$Patient = substr(Myeloid$ID,2,4)
Teff$Patient = substr(Teff$ID,1,3)

#Define Timepoint
B$Timepoint = substr(B$ID,5,8)
Myeloid$Timepoint = substr(Myeloid$ID,6,9)
Teff$Timepoint = substr(Teff$ID,5,8)

#Rename "cystectomy" timepoint as "post"
B$Timepoint[substr(B$Timepoint,1,4)=='Cyst'] = 'Post'
Myeloid$Timepoint[substr(Myeloid$Timepoint,1,4)=='Cyst'] = 'Post'
Teff$Timepoint[substr(Teff$Timepoint,1,4)=='Cyst'] = 'Post'

#Combined Patient-Timepoint identifier
B$comb = paste(B$Patient,B$Timepoint)
Myeloid$comb = paste(Myeloid$Patient,Myeloid$Timepoint)
Teff$comb = paste(Teff$Patient,Teff$Timepoint)

#Only select rows with a Patient-Timepoint identifier
B = B[!is.na(B$comb),]
Myeloid = Myeloid[!is.na(Myeloid$comb),]
Teff = Teff[!is.na(Teff$comb),]

#Combine flow data
flow = full_join(B,Myeloid,by="comb")
flow = full_join(flow,Teff,by="comb")
flow$Patient = substr(flow$comb,1,3)
flow$Live.cells.FSC.A..SSC.A.subset.Single.Cells.Single.Cells.Lineage..CD19..CD19.Ki67.

colnames(flow)

#Remove redundant ID columns
flow = flow[,c(2:19,24:29,33:63,22,64,65)]

#Convert percentages to integers
for (j in 1:55){
  for (i in 1:nrow(flow)){
    flow[i,j] = as.numeric(substr(flow[i,j],1,nchar(flow[i,j])-1))
  }
}


#Convert to numeric
for (j in 1:55){
  flow[,j] = as.numeric(flow[,j])
}


flow = flow[flow$Timepoint%in%c('C1D1','Post'),]

#Define Patient in clinical data
clinical$Patient = as.character(clinical$ID)

#Combine clinical and flow data, remove extra flow point (C2D8 in one patient)
flow_clin = left_join(flow,clinical,by='Patient')

#Read in immune signatures

sigs = read.delim('LCCC1520_immune_score.txt')
sigs = sigs[-c(17,33),]
sigs$Patient = as.numeric(substr(sigs$X,1,3))
sigs$Timepoint = substr(sigs$X,(nchar(sigs$X)-3),nchar(sigs$X))
sigs$Timepoint[sigs$Timepoint=='sttx'] = 'Post'
sigs$Timepoint[sigs$Timepoint=='retx'] = 'C1D1'

sigs$comb = paste(sigs$Patient,sigs$Timepoint)

#Combine with flow cytometry data
fc2 = full_join(flow_clin,sigs,by='comb')
fc2$Timepoint = substr(fc2$comb,5,8)
fc2$Patient = substr(fc2$comb,1,3)



#Read in clinical data
clinical = read.csv('Clinical1520.csv')

#Complete response data frame
complete_response = data.frame(as.character(clinical$ID),clinical$complete_response)
colnames(complete_response) = c('Patient','complete_response')
fc2=full_join(fc2,complete_response,by='Patient')
#Select only non-pCR patients
fc2 = fc2[fc2$complete_response.y=='No',]


#Set up data frame
pre_data = data.frame(matrix(nrow=55,ncol=3))
colnames(pre_data) = c('pop','cor','p')
pre_data$pop = colnames(fc2)[c(1:55)]

for (j in c(1:55)){
  pre3 = na.omit(fc2[,c(j,126)])
  pre_data$cor[j] = cor(pre3[,1],pre3[,2])
  pre_data$p[j] = cor.test(pre3[,1],pre3[,2])$p.value
}


pre_data$padj = p.adjust(pre_data$p,'BH')
pre_data[order(pre_data$p),]
pre_data$color = 'gray'
pre_data$color[pre_data$padj<0.05]='red'
pre_data$labs = ''
pre_data$labs[pre_data$padj<0.05]='eMDSC: Lin- HLADR- CD33+ CD11b+'

#Supplemental Figure 6A
ggplot(pre_data,aes(cor,-log10(p),label=labs))+
  geom_point(aes(color=color),size=4,alpha=0.6)+
  geom_text_repel()+
  scale_color_manual(values=c('gray','darkred'),labels=c('NS','Up, sig.'),name='')+
  theme_bw()+xlab('Pearson R')+
  ggtitle('Pre-and post-tx flow cytometry populations \nvs. IL_8 signature, non-pCR patients')+
  theme(
    title=element_text(face="bold"),
    axis.title.y = element_text(face="bold"),
    axis.title.x = element_text(face="bold"),
    panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
    panel.background = element_blank(), axis.line = element_line(colour = "black"))


#Supplemental Figure 6B
ggplot(fc2,aes(IL_8,`Live.cells.FSC.A..SSC.A.subset.Single.Cells.Single.Cells.Lin.HLADR..eMDSC_Lin.HLADR.CD33.CD11b.`))+
  geom_point(size=3,alpha=0.8,col='darkblue')+
  geom_smooth(method='lm')+stat_cor()+
  theme_bw()+theme(panel.grid.major=element_blank(),panel.grid.minor = element_blank())+
  theme(axis.title=element_text(face="bold"))+
  xlim(-1.7,2.2)+
  xlab('IL-8 signature')+
  ylab('Flow cytometry population %\neMDSC: Lin- HLADR- CD33+ CD11b+')





#Derive MDSC gene signature

#Read in expression data
expr = read.csv('LCCC1520_expr.csv')
colnames(expr) = sub("\\..*", "", colnames(expr))  

mdsc_sig = c('CD14','S100A9')
expr_msig = expr[,(colnames(expr) %in% mdsc_sig)]
expr_msig = expr_msig[substr(expr[,1],1,3)%in%complete_response$Patient[complete_response$complete_response=='No'],]

#Scale the expression values
for (j in 1:ncol(expr_msig)){
  expr_msig[,j] = scale(expr_msig[,j])
}

#Signature as mean value of the two genes by patient
msig = data.frame(expr[substr(expr[,1],1,3)%in%complete_response$Patient[complete_response$complete_response=='No'],1], rowMeans(expr_msig))
colnames(msig) = c('ID','sig')

#Patient, pre and post
msig$Patient = substr(msig$ID,1,3)
msig$Timepoint = 'Post'
msig$Timepoint[substr(msig$ID,nchar(msig$ID)-2,nchar(msig$ID))=='etx']='C1D1'
msig$comb = paste(msig$Patient,msig$Timepoint)
msig2 = full_join(msig,sigs,by='comb')

#No complete responders
msig2 = msig2[msig2$Patient.x%in% complete_response$Patient[complete_response$complete_response=='No'] | msig2$Timepoint.x=='C1D1',]

#Supplemental Figure 6C
ggplot(msig2,aes(IL_8,sig))+
  geom_point(size=3,alpha=0.8,col='darkblue')+
  geom_smooth(method='lm')+stat_cor()+
  theme_bw()+theme(axis.title=element_text(face='bold'))+
  theme(panel.grid.major=element_blank(),panel.grid.minor=element_blank())+
  xlab('IL_8 signature')+ylab('MDSC signature: CD14 & S100A9')



```
