This package will help you to analyze the output of the Fluidigm digital real time qPCR machine to inspect gene expression. You can do this with a simple workflow, that will be explained in detail further down this document.

Setup

library(fluidgr)
library(magrittr)
library(dplyr)
library(stringr)

Simple Workflow

Record the path to your fluidigm CSV data and the name of your reference normalizers.

path_to_data <- system.file("extdata", "sample-fluidigm-run.csv",
                            package = "fluidgr",
                            mustWork = TRUE)

normalizers <- c("normalizer1",
                 "normalizer2",
                 "normalizer3")

Parse them, normalize them and scale them in a magrittr pipe.

fluidigm_data <- 
  path_to_data %>%
  read_fluidigm() %>%
  normalize() %>%
  scale_fluidigm()

And your data are ready to be saved on disk or plotted with ggplot2.

In the next paragraphs you’ll find this same workflow explained in details.

Load your data into R

You can start by loading the output of the Fluidigm digital real time qPCR machine into R. This output is in a standard CSV format with a 10 lines header and triple column names, you can find an example of such file here.

Access the path to that sample CSV file in R with:

path_to_data <- system.file("extdata", "sample-fluidigm-run.csv",
                            package = "fluidgr",
                            mustWork = TRUE)

And load it with the funciton read_fluidigm(). Use simplify = TRUE if you want to keep only the columns that are strictly necessary.

dat <- read_fluidigm(path = path_to_data,
                     simplify = TRUE)
## Parsed with column specification:
## cols(
##   chamber_id = col_character(),
##   sample_name = col_character(),
##   sample_type = col_character(),
##   sample_rconc = col_double(),
##   target_name = col_character(),
##   target_type = col_character(),
##   ct_value = col_double(),
##   ct_calibrated_rconc = col_double(),
##   ct_quality = col_double(),
##   ct_call = col_character(),
##   ct_threshold = col_double(),
##   tm_inrange = col_double(),
##   tm_outrange = col_integer(),
##   tm_peakratio = col_integer(),
##   comments = col_character()
## )

Tidy your Data

After you have parsed the data, you can modify them as you wish using dplyr.

Remove samples

For example, you might want to remove selected samples:

Our example dataset contains samples that are dilution used for calibration curves.

dat$sample_name %>% unique()
##  [1] "H20"           "J-N2R3"        "R- Mix 1/160"  "J-N2R2"       
##  [5] "R- Mix 1/80"   "J-N2R1"        "R- Mix 1/40"   "J-N1R3"       
##  [9] "R- Mix 1/20"   "J-N1R2"        "R- Mix 1/10"   "J-N1R1"       
## [13] "R- Mix"        "J-N4R3"        "J-N4R2"        "I -Mix 1/160" 
## [17] "J-N4R1"        "I -Mix 1/80"   "J-N3R3"        "I -Mix 1/40"  
## [21] "J-N3R2"        "I -Mix 1/20"   "J-N3R1"        "I -Mix 1/10"  
## [25] "G-N2R3"        "I - Mix"       "G-N2R2"        "G-N2R1"       
## [29] "B - Mix 1/160" "G-N1R3"        "B -Mix 1/80"   "G-N1R2"       
## [33] "B -Mix 1/40"   "G-N1R1"        "B -Mix 1/20"   "G-N4R3"       
## [37] "B -Mix 1/10"   "G-N4R2"        "B - Mix"       "G-N4R1"       
## [41] "G-N3R3"        "G-Mix 1/160"   "G-N3R2"        "G-Mix 1/80"   
## [45] "G-N3R1"        "G-Mix 1/40"    "B-N2R3"        "G-Mix 1/20"   
## [49] "B-N2R2"        "G- Mix 1/10"   "B-N2R1"        "G-Mix"        
## [53] "B-N1R3"        "B-N1R2"        "J - Mix 1/160" "B-N1R1"       
## [57] "J - Mix 1/80"  "B-N4R3"        "J - Mix 1/40"  "B-N4R2"       
## [61] "J - Mix 1/20"  "B-N4R1"        "J - Mix 1/10"  "B-N3R3"       
## [65] "J - Mix"       "B-N3R2"        "B-N3R1"        "R-N4R3"       
## [69] "I-N2R3"        "R-N4R2"        "I-N2R2"        "R-N4R1"       
## [73] "I-N2R1"        "R-N3R3"        "I-N1R3"        "R-N3R2"       
## [77] "I-N1R2"        "R-N3R1"        "I-N1R1"        "R-N2R3"       
## [81] "I-N4R3"        "R-N2R2"        "I-N4R2"        "R-N2R1"       
## [85] "I-N4R1"        "R-N1R3"        "I-N3R3"        "R-N1R2"       
## [89] "I-N3R2"        "R-N1R1"        "I-N3R1"

Those samples, all have the word “Mix” in their name, and can be removed with:

dat <- 
  dat %>%
  filter(!sample_name %>% str_detect("Mix"))

One sample “H2O” is a negative control, it also can be removed:

dat <- 
  dat %>%
  filter(sample_name != "H20")

Check measurements per sample

You can check that each sample has been measured the same number of times:

dat$sample_name %>% table()
## .
## B-N1R1 B-N1R2 B-N1R3 B-N2R1 B-N2R2 B-N2R3 B-N3R1 B-N3R2 B-N3R3 B-N4R1 
##      8      8      8      8      8      8      8      8      8      8 
## B-N4R2 B-N4R3 G-N1R1 G-N1R2 G-N1R3 G-N2R1 G-N2R2 G-N2R3 G-N3R1 G-N3R2 
##      8      8      8      8      8      8      8      8      8      8 
## G-N3R3 G-N4R1 G-N4R2 G-N4R3 I-N1R1 I-N1R2 I-N1R3 I-N2R1 I-N2R2 I-N2R3 
##      8      8      8      8      8      8      8      8      8      8 
## I-N3R1 I-N3R2 I-N3R3 I-N4R1 I-N4R2 I-N4R3 J-N1R1 J-N1R2 J-N1R3 J-N2R1 
##      8      8      8      8      8      8      8      8      8      8 
## J-N2R2 J-N2R3 J-N3R1 J-N3R2 J-N3R3 J-N4R1 J-N4R2 J-N4R3 R-N1R1 R-N1R2 
##      8      8      8      8      8      8      8      8      8      8 
## R-N1R3 R-N2R1 R-N2R2 R-N2R3 R-N3R1 R-N3R2 R-N3R3 R-N4R1 R-N4R2 R-N4R3 
##      8      8      8      8      8      8      8      8      8      8
dat$sample_name %>% table() %>% unique()
## [1] 8

Check for duplicated targets

Also, one of the target is a duplicated normalizer. You can remove it with:

dat$target_name %>% unique()
## [1] "normalizer1"    "gene1"          "gene4"          "gene2"         
## [5] "normalizer2"    "normalizer3"    "normalizer1bis" "gene3"
dat <- 
  dat %>%
  filter(target_name != "normalizer1bis")

Load data manually

You can load the digital qPCR gene expression data manually with your favourite functions, and store them as a tibble or a data.frame in R.

For the analysis downstream, three columns are essential:

  • sample_name, where you must store a univocal sample identifier.
  • target_name, where you must store a univocal target identifier (i.e. the gene that you amplify).
  • ct_value, where you must store the Ct value (i.e. threeshold cycle at which the amplicon is detected) as provided by the digital qPCR machine.

Normalize

You must provide the names of the normalizers exactly as they are stored in the target_name column. In this case the name of the normalizers is: normalizer1, normalizer2 and normalizer3.

normalizers <- c("normalizer1",
                 "normalizer2",
                 "normalizer3")

norm_dat <- 
  dat %>% 
  normalize(normalizers = normalizers) 

The normalize() function takes the data parsed by read_fluidigm() as object and returns the same data with two additional columns:

  • norm_geom_mean stores the geometric mean of normalizers for each sample.
  • expression stores the normalized expression values.

Expression values are normalized with the formula:

\[expression = 2^{-(C_T - C_Tnorm)}\]

Where, for each well, \(C_T\) is the recorded threshold cycle (ct_value) and \(C_Tnorm\) is the geometric mean of the normalizers CT values.

This formula is a simplification of the common \(2^{ - \Delta \Delta Ct}\) formula that skips calibration.

This is how your data should look after normalization:

norm_dat %>% head() %>% knitr::kable()
sample_name sample_type target_name target_type ct_value norm_geom_mean expression
J-N2R3 Unknown gene1 Test 5.790066 6.571610 1.71897
J-N2R3 Unknown gene4 Test 15.037867 6.571610 0.00283
J-N2R3 Unknown gene2 Test 9.595607 6.571610 0.12294
J-N2R3 Unknown gene3 Test 9.519824 6.571610 0.12957
J-N2R2 Unknown gene1 Test 5.920355 6.460208 1.45382
J-N2R2 Unknown gene4 Test 16.835858 6.460208 0.00075

Session Info

devtools::session_info()
## ─ Session info ──────────────────────────────────────────────────────────
##  setting  value                       
##  version  R version 3.4.4 (2018-03-15)
##  os       Ubuntu 16.04.5 LTS          
##  system   x86_64, linux-gnu           
##  ui       X11                         
##  language en_US                       
##  collate  en_US.UTF-8                 
##  ctype    en_US.UTF-8                 
##  tz       Europe/Paris                
##  date     2018-12-05                  
## 
## ─ Packages ──────────────────────────────────────────────────────────────
##  package     * version date       lib source        
##  assertthat    0.2.0   2017-04-11 [1] CRAN (R 3.4.4)
##  backports     1.1.2   2017-12-13 [1] CRAN (R 3.4.4)
##  base64enc     0.1-3   2015-07-28 [1] CRAN (R 3.4.4)
##  bindr         0.1.1   2018-03-13 [1] CRAN (R 3.4.4)
##  bindrcpp    * 0.2.2   2018-03-29 [1] CRAN (R 3.4.4)
##  callr         3.0.0   2018-08-24 [1] CRAN (R 3.4.4)
##  cli           1.0.1   2018-09-25 [1] CRAN (R 3.4.4)
##  commonmark    1.6     2018-09-30 [1] CRAN (R 3.4.4)
##  crayon        1.3.4   2017-09-16 [1] CRAN (R 3.4.4)
##  debugme       1.1.0   2017-10-22 [1] CRAN (R 3.4.4)
##  desc          1.2.0   2018-05-01 [1] CRAN (R 3.4.4)
##  devtools      2.0.0   2018-10-19 [1] CRAN (R 3.4.4)
##  digest        0.6.18  2018-10-10 [1] CRAN (R 3.4.4)
##  dplyr       * 0.7.7   2018-10-16 [1] CRAN (R 3.4.4)
##  evaluate      0.12    2018-10-09 [1] CRAN (R 3.4.4)
##  fluidgr     * 0.1     2018-12-05 [1] local         
##  fs            1.2.6   2018-08-23 [1] CRAN (R 3.4.4)
##  glue          1.3.0   2018-07-17 [1] CRAN (R 3.4.4)
##  highr         0.7     2018-06-09 [1] CRAN (R 3.4.4)
##  hms           0.4.2   2018-03-10 [1] CRAN (R 3.4.4)
##  htmltools     0.3.6   2017-04-28 [1] CRAN (R 3.4.4)
##  knitr         1.20    2018-02-20 [1] CRAN (R 3.4.4)
##  magrittr    * 1.5     2014-11-22 [1] CRAN (R 3.4.4)
##  MASS          7.3-50  2018-04-30 [4] CRAN (R 3.4.4)
##  memoise       1.1.0   2017-04-21 [1] CRAN (R 3.4.4)
##  pillar        1.3.0   2018-07-14 [1] CRAN (R 3.4.4)
##  pkgbuild      1.0.2   2018-10-16 [1] CRAN (R 3.4.4)
##  pkgconfig     2.0.2   2018-08-16 [1] CRAN (R 3.4.4)
##  pkgdown       1.1.0   2018-06-02 [1] CRAN (R 3.4.4)
##  pkgload       1.0.1   2018-10-11 [1] CRAN (R 3.4.4)
##  prettyunits   1.0.2   2015-07-13 [1] CRAN (R 3.4.4)
##  processx      3.2.0   2018-08-16 [1] CRAN (R 3.4.4)
##  ps            1.2.0   2018-10-16 [1] CRAN (R 3.4.4)
##  purrr         0.2.5   2018-05-29 [1] CRAN (R 3.4.4)
##  R6            2.3.0   2018-10-04 [1] CRAN (R 3.4.4)
##  Rcpp          0.12.19 2018-10-01 [1] CRAN (R 3.4.4)
##  readr         1.1.1   2017-05-16 [1] CRAN (R 3.4.4)
##  remotes       2.0.1   2018-10-19 [1] CRAN (R 3.4.4)
##  rlang         0.3.0   2018-10-22 [1] CRAN (R 3.4.4)
##  rmarkdown     1.10    2018-06-11 [1] CRAN (R 3.4.4)
##  roxygen2      6.1.0   2018-07-27 [1] CRAN (R 3.4.4)
##  rprojroot     1.3-2   2018-01-03 [1] CRAN (R 3.4.4)
##  rstudioapi    0.8     2018-10-02 [1] CRAN (R 3.4.4)
##  sessioninfo   1.1.0   2018-09-25 [1] CRAN (R 3.4.4)
##  stringi       1.2.4   2018-07-20 [1] CRAN (R 3.4.4)
##  stringr     * 1.3.1   2018-05-10 [1] CRAN (R 3.4.4)
##  testthat      2.0.1   2018-10-13 [1] CRAN (R 3.4.4)
##  tibble        1.4.2   2018-01-22 [1] CRAN (R 3.4.4)
##  tidyselect    0.2.5   2018-10-11 [1] CRAN (R 3.4.4)
##  usethis       1.4.0   2018-08-14 [1] CRAN (R 3.4.4)
##  withr         2.1.2   2018-03-15 [1] CRAN (R 3.4.4)
##  xml2          1.2.0   2018-01-24 [1] CRAN (R 3.4.4)
##  yaml          2.2.0   2018-07-25 [1] CRAN (R 3.4.4)
## 
## [1] /home/otho/R/x86_64-pc-linux-gnu-library/3.4
## [2] /usr/local/lib/R/site-library
## [3] /usr/lib/R/site-library
## [4] /usr/lib/R/library