<jupyter_start><jupyter_text>IntroductionThe purpose of this notebook is to explore profiles of human primary T cells post-electroporation. Our main goal is to identify cells that are more likely to take up and express the plasmid. Our transfection efficiency (as defined by the frequency of GFP positive cells a day after the GFP plasmid electroporation) is relatively low (<%5) for the unstimulated population and relatively high but variable (20-70%) for the activated ones.To see the general characteristics of these GFP positive cells, we electroporated them either in unstimulated form or two-days after bead-based activation. The next day, we stained them to profile their activation and naive/memory status. For activation, we used `CD25` (which is expected to be up-regulated upon activation) and also `CD69` (which is an early activation marker). For the naive/memory phenotype, we used the `CCR7/CD45RO` combination where `CCR7+ CD45RO+` cells are assumed to be `naive`, `CCR7+ CD45RO+` cells to be `central memory`, and `CCR7- CD45RO+` ones to be `effective memory`.With this setup, we can also gate based on `GFP (FITC)` positivity to compare and contrast `GFP+` profiles against `GFP-` ones. Data preparationLet's start with importing the frequency table from FlowJo and transforming it to a form that will allow us easily compare different populations.<jupyter_code>library('readr')
library('magrittr')
library('dplyr')
library('tidyr')
library('ggplot2')<jupyter_output>Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union


Attaching package: ‘tidyr’

The following object is masked from ‘package:magrittr’:

    extract<jupyter_text>We have three donors, two staining strategies, two electroporation conditions, and two cell states. This is how the original table looks originally:<jupyter_code>raw_tbl <-
    read_tsv(
        'flow-data.csv',
        col_types=cols(
            `Sample:`=col_character(),
            `Donor`=col_factor(levels=c('Donor 30', 'Donor 31', 'Donor 33')),
            `Cell state`=col_factor(levels=c('Activated', 'Unstimulated')),
            `Electroporation`=col_factor(levels=c('no DNA', 'NDG plasmid')),
            `Staining`=col_factor(levels=c('Activation status', 'Naive status')),
            .default=col_double()
        )
    )

raw_tbl %>% head
names(raw_tbl)<jupyter_output><empty_output><jupyter_text>We want to transform it so that each observation per population becomes a row:<jupyter_code>flow_data <-
    raw_tbl %>%
    gather(
        key='Population',
        value='Freq_of_Parent',
        factor_key=TRUE,
        `Live/GFP+ | Freq. of Parent`:`Live/CD25- CD69- | Freq. of Parent`
    )

flow_data<jupyter_output><empty_output><jupyter_text>GFP positivityLet's start with checking the transfection efficiency for each of the conditions. The `no DNA` serves as negative control.<jupyter_code>head(flow_data)
flow_data %>%
    filter(`Population` == 'Live/GFP+ | Freq. of Parent') %>%
    group_by(`Donor`, `Cell state`, `Electroporation`) %>%
    summarize(
        `GFP+`=mean(`Freq_of_Parent`),
        `Live`=mean(`Live | Freq. of Parent`)
    ) %>%
    ggplot(aes(x=`Electroporation`, y=`Live`)) +
        geom_col(fill="#7cae00") +
        geom_text(aes(label=`Live`), vjust=-1) +
        facet_wrap(~`Donor`+`Cell state`, ncol=2) +
        ylab('GFP positive population frequency (%)') +
        ylim(0, 100)
flow_data %>%
    filter(`Population` == 'Live/GFP+ | Freq. of Parent') %>%
    group_by(`Donor`, `Cell state`, `Electroporation`) %>%
    summarize(
        `GFP+`=mean(`Freq_of_Parent`),
        `Live`=mean(`Live | Freq. of Parent`),
        `Normalized_GFP+`=(mean(`Freq_of_Parent`)/100.0)*mean(`Live | Freq. of Parent`)
    ) %>%
    ggplot(aes(x=`Electroporation`, y=`Normalized_GFP+`)) +
        geom_col(fill="#7cae00") +
        geom_text(aes(label=`Normalized_GFP+`), vjust=-1) +
        facet_wrap(~`Donor`+`Cell state`, ncol=2) +
        ylab('GFP positive population frequency (%)') +
        ylim(0, 100)
flow_data %>%
    filter(`Population` == 'Live/GFP+ | Freq. of Parent') %>%
    group_by(`Donor`, `Cell state`, `Electroporation`) %>%
    summarize(
        `GFP+`=mean(`Freq_of_Parent`)
    ) %>%
    ggplot(aes(x=`Electroporation`, y=`GFP+`)) +
        geom_col(fill="#7cae00") +
        geom_text(aes(label=`GFP+`), vjust=-1) +
        facet_wrap(~`Donor`+`Cell state`, ncol=2) +
        ylab('GFP positive population frequency (%)') +
        ylim(0, 50)<jupyter_output><empty_output><jupyter_text>Overall population comparisonsLooks like the electroporation did work. Before diving into the detailed comparisons, let's compare `no DNA` and `NDG plasmid` conditions and see if their activation and naive/memory statuses are different. Normally, we don't expect any differences across these two conditions but if there is any difference, it would imply that we are probably killing more of one phenotypic population. Overall population - activation markers<jupyter_code>flow_data %>%
    filter(
        `Staining` == 'Activation status',
        `Population` %in% c(
            'Live/CD25+ CD69+ | Freq. of Parent',
            'Live/CD25+ CD69- | Freq. of Parent',
            'Live/CD25- CD69+ | Freq. of Parent',
            'Live/CD25- CD69- | Freq. of Parent'
        )
    ) %>%
    ggplot(aes(x=`Population`, y=`Freq_of_Parent`, fill=`Electroporation`)) +
        geom_col(position='dodge') +
        facet_wrap(~`Donor`+`Cell state`, ncol=2) +
        ylab('Population frequency (%)') +
        theme(axis.text.x=element_text(angle=75, hjust=1))<jupyter_output><empty_output><jupyter_text>There are some differences across populations but we don't see a huge shift in any of the populations. In the activated cells, the plasmid electroporation seem to favor `CD25+ CD69+` cells only a bit and in the unstimulated ones, `CD25- CD69-` cells seem to be relatively more prevalant compared to NDG plasmid. Overall population - naive/memory phenotype<jupyter_code>flow_data %>%
    filter(
        `Staining` == 'Naive status',
        `Population` %in% c(
            'Live/CCR7+ CD45RO+ | Freq. of Parent',
            'Live/CCR7- CD45RO+ | Freq. of Parent',
            'Live/CCR7+ CD45RO- | Freq. of Parent',
            'Live/CCR7- CD45RO- | Freq. of Parent'
        )
    ) %>%
    ggplot(aes(x=`Population`, y=`Freq_of_Parent`, fill=`Electroporation`)) +
        geom_col(position='dodge') +
        facet_wrap(~`Donor`+`Cell state`, ncol=2) +
        ylab('Population frequency (%)') +
        theme(axis.text.x=element_text(angle=75, hjust=1))<jupyter_output><empty_output><jupyter_text>GFP positive vs GFP negativeAfter making sure that nothing looks weird with our transfection and the transfected populations, let's get the data ready for comparing `GFP positive` population to `GFP negative` one. The general understanding is that if cells are happily proliferating then they are more likely to take up and express the material electroporated to them. If this is true, we expect to see more active GFP positive cells compared to negative ones and also more prevalent CM/EM phenotype within GFP positive ones. Data preparation<jupyter_code>raw_tbl %>% head
gfp_comp_data <-
    rbind(
        raw_tbl %>%
            select(
                `Donor`:`Staining`,
                `Naive: CCR7+ CD45RO-`=`Live/GFP+/CCR7+ CD45RO- | Freq. of Parent`,
                `CM: CCR7+ CD45RO+`=`Live/GFP+/CCR7+ CD45RO+ | Freq. of Parent`,
                `EM: CCR7- CD45RO+`=`Live/GFP+/CCR7- CD45RO+ | Freq. of Parent`,
                `EMRA: CCR7- CD45RO-`=`Live/GFP+/CCR7- CD45RO- | Freq. of Parent`,
                `CD25+ CD69-`=`Live/GFP+/CD25+ CD69- | Freq. of Parent`,
                `CD25+ CD69+`=`Live/GFP+/CD25+ CD69+ | Freq. of Parent`,
                `CD25- CD69+`=`Live/GFP+/CD25- CD69+ | Freq. of Parent`,
                `CD25- CD69-`=`Live/GFP+/CD25- CD69- | Freq. of Parent`
            ) %>%
            mutate(`GFP`="Positive"),
        raw_tbl %>%
            select(
                `Donor`:`Staining`,
                `Naive: CCR7+ CD45RO-`=`Live/GFP-/CCR7+ CD45RO- | Freq. of Parent`,
                `CM: CCR7+ CD45RO+`=`Live/GFP-/CCR7+ CD45RO+ | Freq. of Parent`,
                `EM: CCR7- CD45RO+`=`Live/GFP-/CCR7- CD45RO+ | Freq. of Parent`,
                `EMRA: CCR7- CD45RO-`=`Live/GFP-/CCR7- CD45RO- | Freq. of Parent`,
                `CD25+ CD69-`=`Live/GFP-/CD25+ CD69- | Freq. of Parent`,
                `CD25+ CD69+`=`Live/GFP-/CD25+ CD69+ | Freq. of Parent`,
                `CD25- CD69+`=`Live/GFP-/CD25- CD69+ | Freq. of Parent`,
                `CD25- CD69-`=`Live/GFP-/CD25- CD69- | Freq. of Parent`
            ) %>%
            mutate(`GFP`="Negative")
    ) %>%
    mutate(`GFP`=as.factor(`GFP`)) %>%
    gather(
        key=`Population`,
        value=`Freq_of_Parent`,
        `Naive: CCR7+ CD45RO-`:`CD25- CD69-`
    )

gfp_comp_data %>% head<jupyter_output><empty_output><jupyter_text>GFP positive vs negative -- naive statusThis time, instead of the `NDG plasmid` and `no DNA` comparison, we will be comparing two different GFP statuses: `Negative` and `Positive`.<jupyter_code>options(repr.plot.width=9, repr.plot.height=5)

gfp_comp_data %>%
    filter(
        `Electroporation` == "NDG plasmid",
        `Staining` == 'Naive status',
        `Population` %in% c(
            'CM: CCR7+ CD45RO+',
            'EM: CCR7- CD45RO+',
            'Naive: CCR7+ CD45RO-',
            'EMRA: CCR7- CD45RO-'
        )
    ) %>%
    ggplot(aes(x=`Population`, y=`Freq_of_Parent`, fill=`GFP`)) +
        geom_col(position='dodge') +
        #facet_wrap(~`Cell state`+`Donor`, ncol=3) +
        facet_grid(`Cell state`~`Donor`) +
        ylab('Percent population (%)') +
        theme_bw() +
        theme(axis.text.x=element_text(angle=75, hjust=1))<jupyter_output><empty_output><jupyter_text>Looks like in both the unstimulated and the activated populations, central memory cells are the ones who are getting and expressing the plasmid more compared to the rest of the other phenotypic groups. GFP positive vs negative -- activation statusNow let's do a similar comparison but this time for their activation status:<jupyter_code>gfp_comp_data %>%
    filter(
        `Electroporation` == "NDG plasmid",
        `Staining` == 'Activation status',
        `Population` %in% c(
            'CD25+ CD69+',
            'CD25+ CD69-',
            'CD25- CD69+',
            'CD25- CD69-'
        )
    ) %>%
    ggplot(aes(x=`Population`, y=`Freq_of_Parent`, fill=`GFP`)) +
        geom_col(position='dodge') +
        facet_wrap(~`Donor`+`Cell state`, ncol=2) +
        ylab('Population frequency (%)') +
        theme(axis.text.x=element_text(angle=75, hjust=1))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1350532500918105, 'fraction_numerical': 0.02414616232096952, 'mean_word_length': 3.1465550057099354, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 66, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '484081', 'license': 'Apache-2.0', 'n_tokens_mistral': 3877, 'n_tokens_neox': 3464, 'n_words': 970, 'path': 'notebooks/figure-6/Post-electroporation cellular profiling.ipynb', 'repo_name': 'hammerlab/t-cell-electroporation', 'size': '10892'}