Microbiome
Last updated: 2025-03-24
Checks: 6 1
Knit directory:
McConville_Lab_Microbiome_PMC255A/
This reproducible R Markdown analysis was created with workflowr (version 1.7.1). The Checks tab describes the reproducibility checks that were applied when the results were created. The Past versions tab lists the development history.
The R Markdown file has unstaged changes. To know which version of
the R Markdown file created these results, you’ll want to first commit
it to the Git repo. If you’re still working on the analysis, you can
ignore this warning. When you’re finished, you can run
wflow_publish to commit the R Markdown file and build the
HTML.
Great job! The global environment was empty. Objects defined in the global environment can affect the analysis in your R Markdown file in unknown ways. For reproduciblity it’s best to always run the code in an empty environment.
The command set.seed(20250117) was run prior to running
the code in the R Markdown file. Setting a seed ensures that any results
that rely on randomness, e.g. subsampling or permutations, are
reproducible.
Great job! Recording the operating system, R version, and package versions is critical for reproducibility.
Nice! There were no cached chunks for this analysis, so you can be confident that you successfully produced the results during this run.
Great job! Using relative paths to the files within your workflowr project makes it easier to run your code on other machines.
Great! You are using Git for version control. Tracking code development and connecting the code version to the results is critical for reproducibility.
The results in this page were generated with repository version 3a65c0b. See the Past versions tab to see a history of the changes made to the R Markdown and HTML files.
Note that you need to be careful to ensure that all relevant files for
the analysis have been committed to Git prior to generating the results
(you can use wflow_publish or
wflow_git_commit). workflowr only checks the R Markdown
file, but you know if there are other scripts or data files that it
depends on. Below is the status of the Git repository when the results
were generated:
Ignored files:
Ignored: .Rhistory
Ignored: .Rproj.user/
Ignored: data/raw_data/
Untracked files:
Untracked: analysis/PMC255A_ScreenQC_v4.Rmd
Untracked: analysis/prelim/
Unstaged changes:
Modified: analysis/PMC255A_ScreenComparison.Rmd
Deleted: analysis/PMC255A_ScreenQC_v3.Rmd
Modified: analysis/_site.yml
Note that any generated files, e.g. HTML, png, CSS, etc., are not included in this status report because it is ok for generated content to have uncommitted changes.
These are the previous versions of the repository in which changes were
made to the R Markdown
(analysis/PMC255A_ScreenComparison.Rmd) and HTML
(docs/PMC255A_ScreenComparison.html) files. If you’ve
configured a remote Git repository (see ?wflow_git_remote),
click on the hyperlinks in the table below to view the files as they
were in that past version.
| File | Version | Author | Date | Message |
|---|---|---|---|---|
| Rmd | 3a65c0b | annrann.wong | 2025-03-14 | Update Integration Page |
| html | 3a65c0b | annrann.wong | 2025-03-14 | Update Integration Page |
| Rmd | 4e5953a | annrann.wong | 2025-03-14 | Update Integration Page |
| html | 4e5953a | annrann.wong | 2025-03-14 | Update Integration Page |
| Rmd | afd7a2a | annrann.wong | 2025-03-14 | Update integration data |
| html | afd7a2a | annrann.wong | 2025-03-14 | Update integration data |
| Rmd | 584065d | annrann.wong | 2025-03-12 | Update integration data |
| html | 584065d | annrann.wong | 2025-03-12 | Update integration data |
| Rmd | 8603594 | annrann.wong | 2025-03-12 | Update integration data |
| html | 8603594 | annrann.wong | 2025-03-12 | Update integration data |
| Rmd | 5a8e2f9 | annrann.wong | 2025-03-11 | Added integration |
| html | 5a8e2f9 | annrann.wong | 2025-03-11 | Added integration |
To examine the polarisation potential of BDBM cells from M0 to M1 or M2 in the presence of compounds and different concentrations of polarisation activator.
Kayla Wilson, Ada Koo, McConville Lab, Bedoui Lab
Image analysis of BMDM cells stained with DAPI, ARG, INOS, and BODIPY (CX7 Pro LZR, 9 fields @ 20x) and image analysis of OT-I cells expressing GFP and OT-II cells expressing tdTomato (Cy5 and Cy10, 1 field @ 4x).
CellProfiler 4.2.8
data.table, DT, reshape2, tidyverse, viridis, patchwork
# load the required packages
library(data.table)
library(readxl)
library(DT)
library(reshape2)
library(viridis)
library(tidyverse)
library(flexdashboard)
library(plotly)
library(crosstalk)
library(htmltools)
library(summarywidget)
# fix ggplotly axis labels
layout_ggplotly <- function(gg, x = -0.02, y = -0.08){
# The 1 and 2 goes into the list that contains the options for the x and y axis labels respectively
gg[['x']][['layout']][['annotations']][[1]][['y']] <- x
gg[['x']][['layout']][['annotations']][[2]][['x']] <- y
gg
}
# set the file prefix
prefix <- "KW_PMC255A_PMC255B"
# turn off scientific notation
options(scipen=999)
2024-12-04
BMDM M0
DC/T OT1
DC/T OT2
Library: Custom MCE library
Library plates: 4 (only plates 3 and
4 used in this analysis)
Cell plates per library plate: 24
Per well data is normalised to Stimulated DMSO on a per plate basis.
The raw and normalised (fold change to DMSO) data for all wells across screen runs are read into a dataframe.
# read in data from three comparisons
norm_255a <- read_csv("output/KW_PMC255A_data_norm_melt.csv", show_col_types = FALSE) %>%
filter(grepl("Unstim_M0", Barcode) & grepl("3|4", VCFG_Plate_ID))
norm_255b_ot1 <- read_csv("output/KW_PMC255B_data_norm_melt_OT1.csv", show_col_types = FALSE) %>%
filter(grepl("3|4", VCFG_Plate_ID))
norm_255b_ot2 <- read_csv("output/KW_PMC255B_data_norm_melt_OT2.csv", show_col_types = FALSE) %>%
filter(grepl("3|4", VCFG_Plate_ID))
Non-samples are filtered out, leaving compound only wells and related data.
# filter out compounds and data
norm_255b_ot1_filt <- norm_255b_ot1 %>%
filter(Description == "Sample" & grepl("A", Plate)) %>% #OT1 plateA (low OVA conc)
filter(grepl("MeanArea", Variable) & Hours == 72) %>%
select("VCFG_Plate_ID", "Barcode", "QCL_Sample_Number", "WellID", "Compound_Name", "Concentration", "Units", Raw, Norm = "NormToT0_NormToDMSO+OVA") %>%
mutate(Feature = "MeanAreaOT1")
norm_255b_ot2_filt <- norm_255b_ot2 %>%
filter(Description == "Sample" & grepl("A", Plate)) %>% #OT2 plateA (low OVA conc)
filter(grepl("MeanArea", Variable) & Hours == 96) %>%
select("VCFG_Plate_ID", "Barcode", "WellID", "Compound_Name", "Concentration", "Units", Raw, Norm = "NormToT0_NormToDMSO+OVA") %>%
mutate(Feature = "MeanAreaOT2")
# pivot data into wide form
norm_255a_filt <- norm_255a %>%
filter(Description == "Sample") %>%
select("Feature", "VCFG_Plate_ID", "Barcode", "QCL_Sample_Number", "WellID", "Compound_Name", "Concentration", "Units", "Raw", Norm = "NormToStimDMSO") #%>%
# pivot_wider(names_from = Feature, values_from = c(Raw, Norm), names_glue = "{.value}_{Feature}")
Compounds were sorted into the following viability bins based on the normalised Total DAPI counts:
# calculate viability bins
viability_bin <- norm_255a %>%
filter(Description == "Sample") %>%
group_by(VCFG_Plate_ID, WellID) %>%
reframe(Viability_Bin =
case_when(grepl("DAPI", Feature) & NormToStimDMSO > 1.15 ~ "High",
grepl("DAPI", Feature) & NormToStimDMSO > 0.8 & NormToStimDMSO <= 1.15 ~ "Normal",
grepl("DAPI", Feature) & NormToStimDMSO > 0.5 & NormToStimDMSO <= 0.8 ~ "Moderate",
grepl("DAPI", Feature) & NormToStimDMSO > 0.3 & NormToStimDMSO <= 0.5 ~ "Low",
grepl("DAPI", Feature) & NormToStimDMSO <= 0.3 ~ "VeryLow")) %>%
filter(!is.na(Viability_Bin))
Data from three readouts (Mean Area OT1, OT2, Total DAPI count) are aggregated.
# combine datasets from all data norm of PMC255
norm_comb <- bind_rows(norm_255b_ot1_filt, norm_255b_ot2_filt, norm_255a_filt) %>%
select(-QCL_Sample_Number) %>%
# fix QCL sample number
left_join(., norm_255a_filt %>%
select(WellID, VCFG_Plate_ID, QCL_Sample_Number) %>% distinct(), by = c("WellID", "VCFG_Plate_ID"))
The normalised values have been Robust Z-Scored to the median of all of the test compounds in order to assess the relative strength of each compound. This method can be used to select the strongest and most robust hits from a large dataset. Z-Scores of <= -2 or >= 2 are considered to be significant, but this value must be viewed in combination with the fold change. See the Robust Z-Scoring section of the Methods page for a more information.
Formula:
Robust Z-Score = (sample value - median of all
sample values) / median absolute deviation of all sample values
zscored_comb <- norm_comb %>%
left_join(., viability_bin, by = c("VCFG_Plate_ID", "WellID")) %>%
group_by(Feature) %>%
mutate(Robust_ZScore = (Norm - median(Norm, na.rm = TRUE))/mad(Norm, na.rm = TRUE)) %>%
mutate_if(is.numeric, round, 2)
Robust Z-Scores for all of the test compounds are displayed below.
The plots is interactive. Hover over the points to view the compound
name and other information. The number of hits (unique compound IDs) and
corresponding fold change to DMSO (FC) at Z-Score cut-offs of 2, 3 and 4
are printed below the plots.
# prepare the data
feat_list <- unique(zscored_comb$Feature)[1:2]
data_zscored_plot <- zscored_comb %>%
filter(Feature == feat_list) %>%
unite(Conc, c(Concentration, Units), sep = "") %>%
unite(Treatment, c(Compound_Name, Conc), remove = FALSE) %>%
mutate(Status = ifelse(Robust_ZScore >= 2, "Significant Increase",
ifelse(Robust_ZScore <= -2, "Significant Decrease", "No Change")))
# set order of status for plotting
stat_order <- c("Significant Increase", "Significant Decrease", "No Change")
data_zscored_plot$Status <- factor(data_zscored_plot$Status, levels = stat_order)
# reorder
data_zscored_plot_filt <- data_zscored_plot %>%
group_by(Feature) %>%
arrange(Robust_ZScore) %>%
mutate(Index = 1:n())
# print a plot and dataframe for each feature
for (feature in feat_list) {
# create the feature heading
cat("\n")
cat("\n## ", feature, "\n")
cat("\n")
# create dot plot
snake_plot <- data_zscored_plot_filt %>%
filter(Feature %in% c(feature)) %>%
ggplot(., aes(x = Index,
y = Robust_ZScore,
label = Compound_Name)) +
geom_point(aes(colour = Status,
text = paste('Compound_Name:', Compound_Name,
'<br>Raw:', Raw,
'<br>Norm:', Norm,
'<br>Robust Z-Score:', Robust_ZScore,
'<br>Barcode:', Barcode)),
alpha = 0.8, size = 1.6) +
geom_hline(aes(yintercept = -2), linetype = "dotted", size = 0.3) +
geom_hline(aes(yintercept = 2), linetype = "dotted", size = 0.3) +
labs(x = "Compound",
y = "Z-Score To Sample") +
#scale_y_continuous(breaks = seq(-6, 6, by = 1), limits=c(-6,6)) +
theme_bw() +
theme(#axis.title.y = element_text(margin = margin(t = 0, r = 30, b = 0, l = 30)),
axis.title.y = element_text(margin = margin(t = 0, r = 10, b = 0, l = 10)),
axis.title.x = element_text(size = 1, colour = "white"),
axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
axis.text.y = element_text(colour = "black"),
plot.title = element_text(margin = margin(t = 10, r = 0, b = 5, l = 0), size = 14),
plot.margin = margin(t = 10, r = 30, b = 5, l = 30),
legend.title = element_blank()) +
scale_colour_manual(values = c("#bc3754", "#2a788e", "grey61"), drop = FALSE, name = "")
print(htmltools::tagList(plotly::ggplotly(snake_plot, tooltip = "text")))
cat("\n")
cat("\n")
data_zscored_filt <- zscored_comb %>%
filter(Feature == feature)
hit_count_summary_2 <- data_zscored_filt %>%
mutate(ZScore_Bin = ifelse(Robust_ZScore >= 2, ">= 2",
ifelse(Robust_ZScore <= -2, "<= -2",
"NonSig"))) %>%
filter(!ZScore_Bin == "NonSig") %>%
group_by(ZScore_Bin) %>%
summarise(Equivalent_FC_max = max(Norm),
Equivalent_FC_min = min(Norm),
Hit_Count = n_distinct(QCL_Sample_Number))
hit_count_summary_3 <- data_zscored_filt %>%
mutate(ZScore_Bin = ifelse(Robust_ZScore >= 3, ">= 3",
ifelse(Robust_ZScore <= -3, "<= -3",
"NonSig"))) %>%
filter(!ZScore_Bin == "NonSig") %>%
group_by(ZScore_Bin) %>%
summarise(Equivalent_FC_max = max(Norm),
Equivalent_FC_min = min(Norm),
Hit_Count = n_distinct(QCL_Sample_Number))
hit_count_summary_4 <- data_zscored_filt %>%
mutate(ZScore_Bin = ifelse(Robust_ZScore >= 4, ">= 4",
ifelse(Robust_ZScore <= -4, "<= -4",
"NonSig"))) %>%
filter(!ZScore_Bin == "NonSig") %>%
group_by(ZScore_Bin) %>%
summarise(Equivalent_FC_max = max(Norm),
Equivalent_FC_min = min(Norm),
Hit_Count = n_distinct(QCL_Sample_Number))
hit_count_summary <- rbind(hit_count_summary_2, hit_count_summary_3, hit_count_summary_4) %>%
pivot_longer(c(Equivalent_FC_max, Equivalent_FC_min),
names_to = "Direction", values_to = "Equivalent_FC") %>%
filter(c(grepl('<', ZScore_Bin) & Direction == "Equivalent_FC_max") |
c(grepl('>', ZScore_Bin) & Direction == "Equivalent_FC_min")) %>%
mutate(ZScore_Bin = factor(ZScore_Bin, levels = c(">= 2", ">= 3", ">= 4", "<= -2", "<= -3", "<= -4"))) %>%
complete(ZScore_Bin, fill = list(Hit_Count = 0)) %>%
select(ZScore_Bin, Equivalent_FC, Hit_Count) %>%
arrange(ZScore_Bin) %>%
mutate_if(is.numeric, round, 2)
# display the table
print(htmltools::tagList(datatable(hit_count_summary, extensions = c('Scroller', "FixedColumns"), rownames = FALSE,
options = list(
dom = 'rt',
columnDefs = list(list(className = 'dt-center',targets="_all")),
pageLength = -1,
searching = FALSE,
scrollX = TRUE))))
cat("\n")
} # end the loop
# }
Scatter plots with dots coloured based on viability bins (see cut-off in ‘Viability Binning’ section above) and a matching datatable with dynamic filters. Interactive check boxes and sliders allow for user control. Viability bins can be selected from a list of checkboxes and Robust Z-Score values can be filtered using a slider widget.
Mean Area of OT1 (y-axis) plotted against total DAPI count (x-axis).
Comments: A trend showing a positive correlation
between total DAPI count and mean area for the majority of hits. Few
outliers (e.g. SN02722430 Clobetasol propionate, SN02722427
Methylprednisolone succinate (sodium)) show a normal-high DAPI count
with low Mean Area across all three concentrations.
#set colour palette
colour_palette <- c("High"="#fde725", "Normal"="#35b779", "Moderate"="#31688e", "Low"="#440154", "VeryLow" = "#2E013E")
# set plot order
zscored_comb$Viability_Bin <- factor(zscored_comb$Viability_Bin, levels = c("High", "Normal", "Moderate", "Low", "VeryLow"))
# add an id to not rely only on rownumbers to per well data
zscored_comb_ot1 <- zscored_comb %>%
filter(grepl("MeanAreaOT1|DAPI", Feature)) %>%
pivot_wider(id_cols = c(VCFG_Plate_ID, WellID, QCL_Sample_Number, Compound_Name, Concentration, Units, Viability_Bin), names_from = Feature, values_from = c(Raw, Norm, Robust_ZScore)) %>%
mutate(id = paste("id", 1:n()),
Compound_Name_Unique = if_else(duplicated(Compound_Name), "B", "A")) %>%
select(-"Robust_ZScore_Total_DAPI_Count")
# pivot to form per comp data
zscored_comb_ot1_percomp <- zscored_comb_ot1 %>%
pivot_wider(id_cols = c("Compound_Name", "QCL_Sample_Number"), names_from = Concentration, names_prefix = "Conc", values_from = c(8:12)) %>%
mutate(id = paste("id", 1:n()))
# combine df into a key
shared_zscored_comb_ot1 <- SharedData$new(zscored_comb_ot1, key = ~ id, group = "id")
shared_zscored_comb_ot1_percomp <- SharedData$new(zscored_comb_ot1_percomp, key = ~ id, group = "id")
# create filter check box & slider
filters <- bscols(
list(
filter_checkbox("Viability_Bin", "Viability Bin", shared_zscored_comb_ot1, ~Viability_Bin),
filter_slider("Robust_ZScore_MeanAreaOT1", "OT1 Robust ZScore", shared_zscored_comb_ot1, ~Robust_ZScore_MeanAreaOT1, step = 0.1)))
# create ggplot
p <- ggplot(shared_zscored_comb_ot1, aes(x = Norm_Total_DAPI_Count, y = Norm_MeanAreaOT1,
color = Viability_Bin)) +
geom_point(aes(text = paste0('Compound: ', Compound_Name,'<br>QCL Sample Number: ', QCL_Sample_Number,'<br>WellID:', WellID))) + scale_colour_manual(values = colour_palette, name = "Concentration (uM)", guide = "none") +
xlim(0, 2) +
facet_wrap(~Concentration, labeller = labeller(Concentration = ~ paste0(.x, "uM")))+
theme_bw()
# convert to Plotly
plotly_plot <- ggplotly(p) %>%
highlight("plotly_selected") %>%
layout(showlegend = F)
# combine filters and plot
bscols(widths = c(2, 10), filters, plotly_plot)
Total Dose Count:
Total Unique Compounds:
datatable(shared_zscored_comb_ot1, extensions = c('Buttons', 'Scroller'), rownames = FALSE,
options = list(
dom = 'Blfrtip',
columnDefs = list(list(className = 'dt-center',targets="_all")),
lengthMenu = list(c(5, -1), c('5', 'All')),
pageLength = 5,
buttons = list(list(extend = 'csv',
filename = paste0(prefix, "_OT1vsDAPI_viability")),
list(extend = 'excel',
filename = paste0(prefix, "_OT1vsDAPI_viability"), title = NULL)),
searching = TRUE,
scrollX = TRUE))
datatable(shared_zscored_comb_ot1_percomp, extensions = c('Buttons', 'Scroller'), rownames = FALSE,
options = list(
dom = 'Blfrtip',
columnDefs = list(list(className = 'dt-center',targets="_all")),
lengthMenu = list(c(5, -1), c('5', 'All')),
pageLength = 5,
buttons = list(list(extend = 'csv',
filename = paste0(prefix, "_OT1vsDAPI_viability")),
list(extend = 'excel',
filename = paste0(prefix, "_OT1vsDAPI_viability"), title = NULL)),
searching = TRUE,
scrollX = TRUE))
Mean Area of OT2 (y-axis) plotted against total DAPI count (x-axis).
Comments: A trend showing a positive correlation
between total DAPI count and mean area for the majority of hits. Few
outliers (e.g. SN02722430 Clobetasol propionate) show a normal-high DAPI
count with low Mean Area across all three concentrations.
#set colour palette
colour_palette <- c("High"="#fde725", "Normal"="#35b779", "Moderate"="#31688e", "Low"="#440154", "VeryLow" = "#2E013E")
# set plot order
zscored_comb$Viability_Bin <- factor(zscored_comb$Viability_Bin, levels = c("High", "Normal", "Moderate", "Low", "VeryLow"))
# add an id to not rely only on rownumbers to per well data
zscored_comb_ot2 <- zscored_comb %>%
filter(grepl("MeanAreaOT2|DAPI", Feature)) %>%
pivot_wider(id_cols = c(VCFG_Plate_ID, WellID, QCL_Sample_Number, Compound_Name, Concentration, Units, Viability_Bin), names_from = Feature, values_from = c(Raw, Norm, Robust_ZScore)) %>%
mutate(id = paste("id", 1:n()),
Compound_Name_Unique = if_else(duplicated(Compound_Name), "B", "A")) %>%
select(-"Robust_ZScore_Total_DAPI_Count")
# pivot to form per comp data
zscored_comb_ot2_percomp <- zscored_comb_ot2 %>%
pivot_wider(id_cols = c("Compound_Name", "QCL_Sample_Number"), names_from = Concentration, names_prefix = "Conc", values_from = c(8:12)) %>%
mutate(id = paste("id", 1:n()))
# combine df into a key
shared_zscored_comb_ot2 <- SharedData$new(zscored_comb_ot2, key = ~ id, group = "id")
shared_zscored_comb_ot2_percomp <- SharedData$new(zscored_comb_ot2_percomp, key = ~ id, group = "id")
# create filter check box & slider
filters <- bscols(
list(
filter_checkbox("Viability_Bin", "Viability Bin", shared_zscored_comb_ot2, ~Viability_Bin),
filter_slider("Robust_ZScore_MeanAreaOT2", "OT2 Robust ZScore", shared_zscored_comb_ot2, ~Robust_ZScore_MeanAreaOT2, step = 0.1)))
# create ggplot
p <- ggplot(shared_zscored_comb_ot2, aes(x = Norm_Total_DAPI_Count, y = Norm_MeanAreaOT2,
color = Viability_Bin)) +
geom_point(aes(text = paste0('Compound: ', Compound_Name,'<br>QCL Sample Number: ', QCL_Sample_Number,'<br>WellID:', WellID))) + scale_colour_manual(values = colour_palette, name = "Concentration (uM)", guide = "none") +
xlim(0, 2) +
facet_wrap(~Concentration, labeller = labeller(Concentration = ~ paste0(.x, "uM")))+
theme_bw()
# convert to Plotly
plotly_plot <- ggplotly(p) %>%
highlight("plotly_selected") %>%
layout(showlegend = F)
# combine filters and plot
bscols(widths = c(2, 10), filters, plotly_plot)
Total Dose Count:
Total Unique Compounds:
datatable(shared_zscored_comb_ot2, extensions = c('Buttons', 'Scroller'), rownames = FALSE,
options = list(
dom = 'Blfrtip',
columnDefs = list(list(className = 'dt-center',targets="_all")),
lengthMenu = list(c(5, -1), c('5', 'All')),
pageLength = 5,
buttons = list(list(extend = 'csv',
filename = paste0(prefix, "_OT2vsDAPI_viability")),
list(extend = 'excel',
filename = paste0(prefix, "_OT2vsDAPI_viability"), title = NULL)),
searching = TRUE,
scrollX = TRUE))
datatable(shared_zscored_comb_ot2_percomp, extensions = c('Buttons', 'Scroller'), rownames = FALSE,
options = list(
dom = 'Blfrtip',
columnDefs = list(list(className = 'dt-center',targets="_all")),
lengthMenu = list(c(5, -1), c('5', 'All')),
pageLength = 5,
buttons = list(list(extend = 'csv',
filename = paste0(prefix, "_OT2vsDAPI_viability")),
list(extend = 'excel',
filename = paste0(prefix, "_OT2vsDAPI_viability"), title = NULL)),
searching = TRUE,
scrollX = TRUE))
Mean Area of OT2 (y-axis) plotted against Mean Area of OT1 (x-axis).
Comments: Overall decrease in mean area of OT1 is
reflected in a decrease in mean area of OT2.
#set colour palette
colour_palette <- c("High"="#fde725", "Normal"="#35b779", "Moderate"="#31688e", "Low"="#440154", "VeryLow" = "#2E013E")
# set plot order
zscored_comb$Viability_Bin <- factor(zscored_comb$Viability_Bin, levels = c("High", "Normal", "Moderate", "Low", "VeryLow"))
# add an id to not rely only on rownumbers to per well data
zscored_comb_ot12 <- zscored_comb %>%
filter(grepl("MeanAreaOT1|MeanAreaOT2|DAPI", Feature)) %>%
pivot_wider(id_cols = c(VCFG_Plate_ID, WellID, QCL_Sample_Number, Compound_Name, Concentration, Units, Viability_Bin), names_from = Feature, values_from = c(Raw, Norm, Robust_ZScore)) %>%
mutate(id = paste("id", 1:n()),
Compound_Name_Unique = if_else(duplicated(Compound_Name), "B", "A")) %>%
select(-"Robust_ZScore_Total_DAPI_Count")
# pivot to form per comp data
zscored_comb_ot12_percomp <- zscored_comb_ot12 %>%
pivot_wider(id_cols = c("Compound_Name", "QCL_Sample_Number"), names_from = Concentration, names_prefix = "Conc", values_from = c(8:15)) %>%
mutate(id = paste("id", 1:n()))
# combine df into a key
shared_zscored_comb_ot12 <- SharedData$new(zscored_comb_ot12, key = ~ id, group = "id")
shared_zscored_comb_ot12_percomp <- SharedData$new(zscored_comb_ot12_percomp, key = ~ id, group = "id")
# create filter check box & slider
filters <- bscols(
list(
filter_checkbox("Viability_Bin", "Viability Bin", shared_zscored_comb_ot12, ~Viability_Bin),
filter_slider("Robust_ZScore_MeanAreaOT1", "OT1 Robust ZScore", shared_zscored_comb_ot12, ~Robust_ZScore_MeanAreaOT1, step = 0.1),
filter_slider("Robust_ZScore_MeanAreaOT2", "OT2 Robust ZScore", shared_zscored_comb_ot12, ~Robust_ZScore_MeanAreaOT2, step = 0.1)))
# create ggplot
p <- ggplot(shared_zscored_comb_ot12, aes(x = Norm_MeanAreaOT1, y = Norm_MeanAreaOT2,
color = Viability_Bin)) +
geom_point(aes(text = paste0('Compound: ', Compound_Name,'<br>QCL Sample Number: ', QCL_Sample_Number,'<br>WellID:', WellID))) + scale_colour_manual(values = colour_palette, name = "Concentration (uM)", guide = "none") +
# xlim(0, 2) +
facet_wrap(~Concentration, labeller = labeller(Concentration = ~ paste0(.x, "uM")))+
theme_bw()
# convert to Plotly
plotly_plot <- ggplotly(p) %>%
highlight("plotly_selected") %>%
layout(showlegend = F)
# combine filters and plot
bscols(widths = c(2, 10), filters, plotly_plot)
Total Dose Count:
Total Unique Compounds:
datatable(shared_zscored_comb_ot12, extensions = c('Buttons', 'Scroller'), rownames = FALSE,
options = list(
dom = 'Blfrtip',
columnDefs = list(list(className = 'dt-center',targets="_all")),
lengthMenu = list(c(5, -1), c('5', 'All')),
pageLength = 5,
buttons = list(list(extend = 'csv',
filename = paste0(prefix, "_OT1vsOT2_viability")),
list(extend = 'excel',
filename = paste0(prefix, "_OT1vsOT2_viability"), title = NULL)),
searching = TRUE,
scrollX = TRUE))
datatable(shared_zscored_comb_ot12_percomp, extensions = c('Buttons', 'Scroller'), rownames = FALSE,
options = list(
dom = 'Blfrtip',
columnDefs = list(list(className = 'dt-center',targets="_all")),
lengthMenu = list(c(5, -1), c('5', 'All')),
pageLength = 5,
buttons = list(list(extend = 'csv',
filename = paste0(prefix, "_OT1vsOT2_viability")),
list(extend = 'excel',
filename = paste0(prefix, "_OT1vsOT2_viability"), title = NULL)),
searching = TRUE,
scrollX = TRUE))
Analysed by Ann Rann Wong
Victorian Centre for Functional Genomics
sessionInfo()
R version 4.4.2 (2024-10-31)
Platform: x86_64-pc-linux-gnu
Running under: Rocky Linux 9.5 (Blue Onyx)
Matrix products: default
BLAS/LAPACK: FlexiBLAS OPENBLAS-OPENMP; LAPACK version 3.9.0
locale:
[1] LC_CTYPE=en_AU.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_AU.UTF-8 LC_COLLATE=en_AU.UTF-8
[5] LC_MONETARY=en_AU.UTF-8 LC_MESSAGES=en_AU.UTF-8
[7] LC_PAPER=en_AU.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_AU.UTF-8 LC_IDENTIFICATION=C
time zone: Australia/Melbourne
tzcode source: system (glibc)
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] summarywidget_0.0.0.9000 htmltools_0.5.8.1 crosstalk_1.2.1
[4] plotly_4.10.4 flexdashboard_0.6.2 lubridate_1.9.4
[7] forcats_1.0.0 stringr_1.5.1 dplyr_1.1.4
[10] purrr_1.0.4 readr_2.1.5 tidyr_1.3.1
[13] tibble_3.2.1 ggplot2_3.5.1 tidyverse_2.0.0
[16] viridis_0.6.5 viridisLite_0.4.2 reshape2_1.4.4
[19] DT_0.33 readxl_1.4.4 data.table_1.17.0
[22] workflowr_1.7.1
loaded via a namespace (and not attached):
[1] gtable_0.3.6 xfun_0.51 bslib_0.9.0 htmlwidgets_1.6.4
[5] processx_3.8.6 callr_3.7.6 tzdb_0.4.0 vctrs_0.6.5
[9] tools_4.4.2 ps_1.9.0 generics_0.1.3 parallel_4.4.2
[13] pkgconfig_2.0.3 lifecycle_1.0.4 compiler_4.4.2 git2r_0.35.0
[17] munsell_0.5.1 getPass_0.2-4 httpuv_1.6.15 sass_0.4.9
[21] yaml_2.3.10 lazyeval_0.2.2 crayon_1.5.3 later_1.4.1
[25] pillar_1.10.1 jquerylib_0.1.4 whisker_0.4.1 cachem_1.1.0
[29] mime_0.12 tidyselect_1.2.1 digest_0.6.37 stringi_1.8.4
[33] labeling_0.4.3 rprojroot_2.0.4 fastmap_1.2.0 grid_4.4.2
[37] colorspace_2.1-1 cli_3.6.4 magrittr_2.0.3 withr_3.0.2
[41] scales_1.3.0 promises_1.3.2 bit64_4.6.0-1 timechange_0.3.0
[45] rmarkdown_2.29 httr_1.4.7 bit_4.5.0.1 gridExtra_2.3
[49] cellranger_1.1.0 hms_1.1.3 memoise_2.0.1 shiny_1.10.0
[53] evaluate_1.0.3 knitr_1.49 rlang_1.1.5 Rcpp_1.0.14
[57] xtable_1.8-4 glue_1.8.0 vroom_1.6.5 rstudioapi_0.17.1
[61] jsonlite_1.9.1 R6_2.6.1 plyr_1.8.9 fs_1.6.5