## ----load-panel-name---------------------------------------------------------- library(beadplexr) panel_info <- load_panel(.panel_name = "Human Growth Factor Panel (13-plex)") panel_info$panel_name # Is equavalent to panel_info <- load_panel(.panel_pattern = ".*rowth.*panel") panel_info$panel_name ## ----content-panel-example, echo=FALSE---------------------------------------- res <- readLines(system.file("resources/legendplex_human_growth_factor_panel_13-plex.yml", package = "beadplexr")) cat(paste(res, collapse = "\n")) ## ---- eval=FALSE-------------------------------------------------------------- # system.file(package = "beadplexr") ## ----load-lplex-data, message=FALSE, warning=FALSE---------------------------- library(beadplexr) library(dplyr) library(purrr) data(lplex) ## ----fsc-ssc-ident-1, fig.width=4--------------------------------------------- plex_sub_sample <- lplex[[1]] plex_sub_sample <- identify_analyte(plex_sub_sample, .parameter = c("FSC-A", "SSC-A"), .analyte_id = c("A", "B"), .column_name = "Bead group") facs_plot(plex_sub_sample, .x = "FSC-A", .y = "SSC-A", .beads = "Bead group") ## ----fsc-ssc-ident-2, fig.width=4--------------------------------------------- plex_sub_sample$`Bead group` <- NULL plex_sub_sample <- identify_analyte(plex_sub_sample, .parameter = c("FSC-A", "SSC-A"), .analyte_id = c("A", "B"), .column_name = "Bead group", .trim = 0.03) facs_plot(plex_sub_sample, .x = "FSC-A", .y = "SSC-A", .beads = "Bead group") ## ----bead-ident, fig.show='hold'---------------------------------------------- library(ggplot2) panel_info <- load_panel(.panel_name = "Human Growth Factor Panel (13-plex)") bead_a <- plex_sub_sample |> filter(`Bead group` == "A") bead_b <- plex_sub_sample |> filter(`Bead group` == "B") bead_a <- identify_analyte(bead_a, .parameter = c("FL6-H"), .analyte_id = names(panel_info$analytes$A), .column_name = "Analyte ID") bead_b <- identify_analyte(bead_b, .parameter = c("FL6-H"), .analyte_id = names(panel_info$analytes$B), .column_name = "Analyte ID") # Factors are added for nicer plotting bead_a[["Analyte ID"]] <- factor(bead_a[["Analyte ID"]], levels = names(panel_info$analytes$A)) bead_b[["Analyte ID"]] <- factor(bead_b[["Analyte ID"]], levels = names(panel_info$analytes$B)) # Since the plot functions return a ggplot, we can easily add to these facs_density1d(bead_a, .x = "FL6-H", .beads = "Analyte ID") + ggtitle("Group A") facs_scatter(bead_a, .x = "FL2-H", .y = "FL6-H", .beads = "Analyte ID") + ggtitle("Group A") facs_density1d(bead_b, .x = "FL6-H", .beads = "Analyte ID") + ggtitle("Group B") facs_scatter(bead_b, .x = "FL2-H", .y = "FL6-H", .beads = "Analyte ID") + ggtitle("Group B") ## ----trim-analyte, fig.show='hold', eval=FALSE-------------------------------- # bead_a |> ( # function(x) # split(x, list(x$`Analyte ID`)) # )() |> # map_df(trim_population, .parameter = c("FL6-H", "FL2-H"), # .column_name = "Analyte ID", # .trim = 0.1) |> # # The trim_population removes all factors # mutate(`Analyte ID` = factor(`Analyte ID`, levels = names(panel_info$analytes$A))) |> # facs_scatter(.x = "FL2-H", .y = "FL6-H", .beads = "Analyte ID") + ggtitle("Group A") # # bead_b |> ( # function(x) # split(x, list(x$`Analyte ID`)) # )() |> # map_df(trim_population, .parameter = c("FL6-H", "FL2-H"), # .column_name = "Analyte ID", # .trim = 0.1) |> # # The trim_population removes all factors # mutate(`Analyte ID` = factor(`Analyte ID`, levels = names(panel_info$analytes$B))) |> # facs_scatter(.x = "FL2-H", .y = "FL6-H", .beads = "Analyte ID") + ggtitle("Group B") ## ---- fig.show='hold', cache=TRUE--------------------------------------------- panel_info <- load_panel(.panel_name = "Human Growth Factor Panel (13-plex)") args_ident_analyte <- list(fs = list(.parameter = c("FSC-A", "SSC-A"), .column_name = "Bead group", .method = "mclust", .trim = 0.03), analytes = list(.parameter = "FL6-H", .column_name = "Analyte ID")) analytes_identified <- identify_legendplex_analyte(df = lplex[[1]], .analytes = panel_info$analytes, .method_args = args_ident_analyte) |> mutate(tmp_aid = `Analyte ID`) |> nest_by(tmp_aid) |> mutate(data = list(trim_population(data, .parameter = c("FL6-H", "FL2-H"), .column_name = "Analyte ID", .trim = 0.1))) |> reframe(data) analytes_identified |> facs_plot(.x = "FSC-A", .y = "SSC-A", .beads = "Bead group") analytes_identified |> filter(`Bead group` == "A") |> facs_plot(.x = "FL2-H", .y = "FL6-H", .beads = "Analyte ID") analytes_identified |> filter(`Bead group` == "B") |> facs_plot(.x = "FL2-H", .y = "FL6-H", .beads = "Analyte ID") ## ----find-analytes------------------------------------------------------------ find_and_trim <- function(df){ identify_legendplex_analyte( df, .analytes = panel_info$analytes, .method_args = args_ident_analyte) |> mutate(tmp_aid = `Analyte ID`) |> nest_by(tmp_aid) |> mutate(data = list( trim_population(data, .parameter = c("FL6-H", "FL2-H"), .column_name = "Analyte ID", .trim = 0.1))) |> reframe(data) } analytes_identified <- lplex |> lapply(find_and_trim) ## ----visualize-analytes, message=FALSE, fig.width=7--------------------------- library(gridExtra) plot_side_by_side <- function(df, .cur_sample){ plot_all_beads <- df |> facs_plot(.x = "FSC-A", .y = "SSC-A", .beads = "Bead group") + ggtitle("All events") plot_a_beads <- df |> filter(`Bead group` == "A") |> facs_plot(.x = "FL2-H", .y = "FL6-H", .beads = "Analyte ID") + ggtitle("Bead group A") plot_b_beads <- df |> filter(`Bead group` == "B") |> facs_plot(.x = "FL2-H", .y = "FL6-H", .beads = "Analyte ID") + ggtitle("Bead group B") arrangeGrob(plot_all_beads, plot_a_beads, plot_b_beads, nrow = 1, ncol = 3, top = .cur_sample) } analytes_identified[1] |> ( function(x) map2(x, names(x), plot_side_by_side) )() |> walk(grid.arrange) ## ----save-plots, eval=FALSE--------------------------------------------------- # # all_plots <- analytes_identified |> ( # function(x) # map2(x, names(x), plot_side_by_side) # )() |> # marrangeGrob(ncol = 1, nrow = 4, top = NA) # # ggsave(filename = "dot_plot.pdf", plot = all_plots, width = 8.27, height = 11.69) # ## ----calculate-mfi------------------------------------------------------------ analyte_mfi <- analytes_identified |> map_df(calc_analyte_mfi, .parameter = "FL2-H", .column_name = "Analyte ID", .mean_fun = "geometric", .id = "Sample") |> mutate(`FL2-H` = log10(`FL2-H`)) |> filter(!is.na(`Analyte ID`)) ## ----split-data--------------------------------------------------------------- library(stringr) # All standard samples have the pattern C[number] standard_data <- analyte_mfi |> filter(str_detect(Sample, "C[0-9]")) # All non standards are samples... we could also filter on S[number] sample_data <- analyte_mfi |> filter(!str_detect(Sample, "C[0-9]")) ## ----calc-std-conc------------------------------------------------------------ # Helper function to extract the sample number as_numeric_standard_id <- function(.s){ .s |> str_extract("C[0-9]") |> str_sub(start = -1L) |> as.numeric() } standard_data <- standard_data |> mutate(`Sample number` = as_numeric_standard_id(Sample)) |> left_join(as_data_frame_analyte(panel_info$analytes), by = "Analyte ID") |> group_by(`Analyte ID`) |> mutate( Concentration = calc_std_conc( `Sample number`, concentration, .dilution_factor = panel_info$std_dilution ) ) |> mutate(Concentration = log10(Concentration)) |> dplyr::select(-concentration, -`Bead group`) ## ----combine-data------------------------------------------------------------- library(tidyr) # It seems that tidyr::nest has problems with non-standard names, so the names # must all be concerted to syntactically valid column names. standard_data <- standard_data |> ungroup() |> ( function(x) setNames(x, make.names(names(x))) )() |> nest(`Standard data` = c(-`Analyte.ID`, -name)) sample_data <- sample_data |> ungroup() |> ( function(x) setNames(x, make.names(names(x))) )() |> nest(`Sample data` = c(-`Analyte.ID`)) plex_data <- inner_join(standard_data, sample_data, by = "Analyte.ID") ## ----fit-standard-curve------------------------------------------------------- library(purrr) # When clustering is performed with mclust, the package mclust is loaded in the # background (an unfortunate necessity). The mclust package also has a function # called `map`, so an unlucky side effect of clustering with mclust, is that we # need to be specify which map function we use plex_data <- plex_data |> group_by(Analyte.ID) |> mutate(`Model fit` = purrr::map(`Standard data`, fit_standard_curve)) |> ungroup() ## ----example-std-curve, echo=FALSE-------------------------------------------- plex_data <- plex_data |> mutate(`Std curve` = purrr::map2(`Standard data`, `Model fit`, plot_std_curve)) plex_data[2, "Std curve"][[1]][[1]] ## ----calc-conc---------------------------------------------------------------- plex_data <- plex_data |> group_by(Analyte.ID) |> mutate(`Standard data` = purrr::map2(`Standard data`, `Model fit`, calculate_concentration)) |> mutate(`Sample data` = purrr::map2(`Sample data`, `Model fit`, calculate_concentration)) |> mutate(`Std conc` = purrr::map(`Standard data`, plot_target_est_conc)) |> mutate(`Est curve` = purrr::pmap(list(`Sample data`, `Standard data`, `Model fit`, name), plot_estimate)) ## ----example-comb-plots, eval=TRUE-------------------------------------------- comb_plots <- function(..., .title, .ncol, .nrow = 1){ .grobs <- list(...) if(missing(.ncol)){ .ncol <- length(.grobs) } gridExtra::marrangeGrob(grobs = .grobs, ncol = .ncol, nrow = .nrow, top = .title) } plex_data <- plex_data |> mutate(`Std plots` = pmap(list(`Std curve`, `Std conc`, .title = name), comb_plots)) ## ----example-std-plots, fig.width=3, echo=FALSE, fig.show='hold'-------------- plex_data[2, "Std plots"][[1]][[1]] plex_data[2, "Est curve"][[1]][[1]] ## ----example-save-std-plot, eval=FALSE---------------------------------------- # plots_to_save <- gridExtra::marrangeGrob(plex_data$`Std plots` |> list_flatten(), # ncol = 1, nrow = 6) # # ggsave("std_plots.pdf", plot = plots_to_save, # path = "./", width = 210, height = 297, units = "mm", # title = "Standard plots") ## ----example-save-est-plot, eval=FALSE---------------------------------------- # plots_to_save <- gridExtra::marrangeGrob(plex_data$`Est curve`, # ncol = 1, nrow = 6) # # ggsave("estimation_curve.pdf", plot = plots_to_save, # path = "./", width = 210, height = 297, units = "mm", # title = "Samples on std curve") ## ----example-extract-conc, eval=FALSE----------------------------------------- # plex_data |> # unnest(`Sample data`) |> # mutate(Calc.conc = 10^Calc.conc, `Calc.conc error` = 10^`Calc.conc error`) ## ----results='markup', echo=FALSE--------------------------------------------- sessionInfo()