library(xcms)
library(tidyverse)
library(plotly)

Introduction

In the previous demo we have been dealing with peak picking, so we assume that we have now a list of chromatographic peaks which have been detected across the full set of samples.

The next step in the process is now to “match” these list of peaks in a consensus list of features which will be the variables which will be present in the final data matrix.

This process of matching is necessary to compensate:

In general, the first phenomenon is less important than the second: when you buy a very expensive mass spectrometer, the instrument producer will do its best to keep mass accuracy as high as possible. On that dimension you, basically, do binning. Chromatographic stability, on the other, end is by far less easy to control.

We start reading in the pick picked data:

load("wines.RData")

We already know that our dataset contains blank injections. They could be used to identify an exclusion list, but for now let’s take them out:

## identify non blank indices
no_blank_id <- which(raw_data$variety != "blank")
## subset the data with a specific xcms function
raw_data <- filterFile(raw_data, file = no_blank_id)
## check the metadata
pData(raw_data)
## # A tibble: 26 × 9
##    filepath              fname inj_ord color variety bottle rep   polarity mode 
##    <chr>                 <chr> <chr>   <chr> <chr>   <chr>  <chr> <chr>    <chr>
##  1 ../data/wines/x002_X… x002… x002    X     QC      X      1     NEG      DDA  
##  2 ../data/wines/x003_X… x003… x003    X     QC      X      2     NEG      DDA  
##  3 ../data/wines/x004_r… x004… x004    red   sangio  B      1     NEG      DDA  
##  4 ../data/wines/x005_r… x005… x005    red   ptnoir  A      1     NEG      DDA  
##  5 ../data/wines/x006_r… x006… x006    red   merlot  A      1     NEG      DDA  
##  6 ../data/wines/x007_w… x007… x007    wht   vermen  A      1     NEG      DDA  
##  7 ../data/wines/x008_r… x008… x008    red   cannon  A      1     NEG      DDA  
##  8 ../data/wines/x009_w… x009… x009    wht   chardo  B      1     NEG      DDA  
##  9 ../data/wines/x010_w… x010… x010    wht   chardo  A      1     NEG      DDA  
## 10 ../data/wines/x011_r… x011… x011    red   lagrei  B      1     NEG      DDA  
## # ℹ 16 more rows

Let’s now visualize the amount of retention time shift looking to the ionic trace of compound which should be present in almost all samples:

# extract the chromatogram
chr_raw <- chromatogram(raw_data, 
                        mz = 295.0445 + 0.01*c(-1, 1), 
                        rt = 250 + 20*c(-1, 1),
                        include = "none")

The include = "none" argument is used to force xcms to read the raw data, the same function can indeed be used to extract the EIC only of the ions which show a chromatrographic peak in that interval.

Find the CP in the slice:

sub_peaks <- chromPeaks(raw_data) %>% 
  as_tibble() %>% 
  filter(between(mz, 295.03,295.05)) %>% 
  filter(between(rt, 230,270))
library(RColorBrewer)
group_colors <- paste0(brewer.pal(3, "Set1"), "60")
names(group_colors) <- c("red","wht","X")
plot(chr_raw, col = group_colors[raw_data$color])
legend("topright", legend = c("red","white", "X"), col = group_colors, lty = 1)
abline(v = sub_peaks$rt, col = "red", lty = 3)

Here we have a tricky situation. The peaks are not aligned, even if the shift is really small, moreover this is actually a double feature, which is also potential biomarker for color and variety … so we should go back to peak detection and play around ;-) to be able to identify the two peaks.

Anyway, let’s try to correct the RT shift. As usual in xcms this can be done in different ways, here we will use the most simple solution (a potentially more flexible one based on dynamic time warping is also available).

What we will do is to apply this algorithm on the QCs and the extrapolate the estimated RT correction on the samples. The rationale behind this choice is the following: samples could be chemically different so it could be in principle possible to misinterpret a chemical difference (which produces a difference in RT) with a retention time shift of analytical origin.

If I use QCs to do that the chemical nature of the samples is the same so every difference is coming from analytical drifts!

The idea behind retention time correction is quite simple:

The first thing to do is to identify the house keeping groups:

The parameters here are:

raw_data <- groupChromPeaks(
  raw_data, 
  param = PeakDensityParam(sampleGroups = raw_data$color,
                           minFraction = 2/3,           
                           binSize = 0.02,  ## width of the slices
                           bw = 3))  ## bandwidth of the density used to find the consensus position

After this grouping, the retention time correction is performed working:

raw_data <- adjustRtime(
  raw_data, 
  param = PeakGroupsParam(minFraction = 1,
                          subset = which(raw_data$variety == "QC"), span = 0.4))
## Performing retention time correction using 629 peak groups.
## Aligning sample number 3 against subset ... OK
## Aligning sample number 4 against subset ... OK
## Aligning sample number 5 against subset ... OK
## Aligning sample number 6 against subset ... OK
## Aligning sample number 7 against subset ... OK
## Aligning sample number 8 against subset ... OK
## Aligning sample number 9 against subset ... OK
## Aligning sample number 10 against subset ... OK
## Aligning sample number 11 against subset ... OK
## Aligning sample number 12 against subset ... OK
## Aligning sample number 15 against subset ... OK
## Aligning sample number 16 against subset ... OK
## Aligning sample number 17 against subset ... OK
## Aligning sample number 18 against subset ... OK
## Aligning sample number 19 against subset ... OK
## Aligning sample number 20 against subset ... OK
## Aligning sample number 21 against subset ... OK
## Aligning sample number 22 against subset ... OK
## Aligning sample number 23 against subset ... OK
## Aligning sample number 24 against subset ... OK
## Applying retention time adjustment to the identified chromatographic peaks ... OK
plotAdjustedRtime(raw_data, col = group_colors[raw_data$color])

So the retention time correction here really small, speaking of a remarkable analytical reproducibility. In general the reproducibility of the chromatography is considered good if the required shift is smaller than the typical chromatographic width. This is anyway a rule of thumb since everything is very much dependent on the analytical method. The black dots show the position of the housekeeping groups which were used to estimate the extent of retention time correction on the QCs.

After retention time correction is now time to move from chromatographic peaks to features. With this term we define a set of consensus groups of peaks which can be used reliably to measure the intensity of a given ion across all samples. If you look to the overall pre-processing from a distant perspective, what we have been basically doing is to try to compensate in a clever and intelligent way for mz inaccuracies and retention time shifts, and the core of the riddle is that the samples are actually (and luckily different).

Features are obtained by a further grouping of the chromatographic peaks after retention time correction:

raw_data <- groupChromPeaks(
  raw_data, 
  param = PeakDensityParam(sampleGroups = raw_data$color,
                           minFraction = 2/3,           
                           binSize = 0.02,  ## width of the slices
                           bw = 3))  ## bandwidth of the density used to find the consensus position

Let’s mow look top their definition

## extract them from the grouped 
features <- featureDefinitions(raw_data)
head(features)
## DataFrame with 6 rows and 12 columns
##           mzmed     mzmin     mzmax     rtmed     rtmin     rtmax    npeaks
##       <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> <numeric>
## FT001   56.5699   56.5698   56.5699  274.4321  273.0029  275.6861         8
## FT002   59.0140   59.0139   59.0141   52.5710   51.2949   53.7408        17
## FT003   65.6779   65.6779   65.6780   61.2852   60.2421   68.9642        10
## FT004   65.6779   65.6779   65.6779   79.8001   78.4873   80.2757         9
## FT005   68.4565   68.4564   68.4565  182.2209  179.7875  183.5496        17
## FT006   68.4565   68.4564   68.4565  163.1186  161.3699  171.1034        10
##             red       wht         X            peakidx  ms_level
##       <numeric> <numeric> <numeric>             <list> <integer>
## FT001         8         0         0 1875,2539,3298,...         1
## FT002         6         6         5  405, 730,1460,...         1
## FT003         9         0         0 1546,2883,4377,...         1
## FT004         9         0         0 1545,2882,4376,...         1
## FT005         3         8         6  292,1010,1713,...         1
## FT006         2         2         6  293,1011,1714,...         1

The df is quite rich:

Let’s dig more on this. For example, can we visualize the position of the peaks assigned to FT005. The idx are the indexes of the row in the peak table:

idx_F005 <- features["FT005","peakidx"][[1]]

Let’s plot them across the retention time:

chromPeaks(raw_data) %>% 
  as_tibble() %>% 
  slice(idx_F005) %>% 
  ggplot() + 
  geom_density(aes(x = rt), bw = 3) + 
  geom_rug(aes(x = rt)) +
  geom_vline(xintercept = features["FT005","rtmed"], col = "red", lty = 2) + 
  xlim(140, 200) + 
  theme_bw()

Here the rug show the position of the chromatigraphic peaks, the line is the density profile (not a chromatrographic trace!) and the red line is our best “estimate” of the true position of the feature

Ok now that we have the definition of the features, let’s get the final data matrix! Mind the gap! We will need to transpose it to get it into the standard R shape.

DM <- featureValues(raw_data, value = "into") 
head(DM)
##       x002_X_QC_X_1_NEG_DDA.mzML x003_X_QC_X_2_NEG_DDA.mzML
## FT001                         NA                         NA
## FT002                   986147.4                   975746.5
## FT003                         NA                         NA
## FT004                         NA                         NA
## FT005                   947277.0                   802055.4
## FT006                   438418.3                   401059.7
##       x004_red_sangio_B_1_NEG_DDA.mzML x005_red_ptnoir_A_1_NEG_DDA.mzML
## FT001                         716179.8                          1131380
## FT002                         708724.8                               NA
## FT003                         475746.8                               NA
## FT004                         981039.5                               NA
## FT005                        1505677.8                               NA
## FT006                         614215.3                               NA
##       x006_red_merlot_A_1_NEG_DDA.mzML x007_wht_vermen_A_1_NEG_DDA.mzML
## FT001                          1035399                               NA
## FT002                           987357                               NA
## FT003                           717797                               NA
## FT004                          1070249                               NA
## FT005                               NA                          1066122
## FT006                               NA                               NA
##       x008_red_cannon_A_1_NEG_DDA.mzML x009_wht_chardo_B_1_NEG_DDA.mzML
## FT001                               NA                               NA
## FT002                         735192.5                               NA
## FT003                         332599.6                               NA
## FT004                         685215.9                               NA
## FT005                               NA                          1280785
## FT006                               NA                               NA
##       x010_wht_chardo_A_1_NEG_DDA.mzML x011_red_lagrei_B_1_NEG_DDA.mzML
## FT001                               NA                        1674083.6
## FT002                         631526.5                               NA
## FT003                               NA                         266367.1
## FT004                               NA                         726500.5
## FT005                        1409850.9                               NA
## FT006                               NA                               NA
##       x012_wht_moscat_A_1_NEG_DDA.mzML x013_wht_ptgrig_C_1_NEG_DDA.mzML
## FT001                               NA                               NA
## FT002                               NA                               NA
## FT003                               NA                               NA
## FT004                               NA                               NA
## FT005                          1324338                         900748.1
## FT006                               NA                               NA
##       x015_X_QC_X_3_NEG_DDA.mzML x016_X_QC_X_4_NEG_DDA.mzML
## FT001                         NA                         NA
## FT002                         NA                  1127542.5
## FT003                         NA                         NA
## FT004                         NA                         NA
## FT005                   952594.7                   794963.6
## FT006                   493059.5                   513929.8
##       x017_wht_ptgrig_B_1_NEG_DDA.mzML x018_red_ptnoir_B_1_NEG_DDA.mzML
## FT001                               NA                               NA
## FT002                         759701.4                        1010649.1
## FT003                               NA                         510139.4
## FT004                               NA                        1893196.4
## FT005                        1751762.1                        1680198.6
## FT006                         939508.5                         627432.0
##       x019_wht_sauvig_A_1_NEG_DDA.mzML x020_wht_gewurz_A_1_NEG_DDA.mzML
## FT001                               NA                               NA
## FT002                         895189.3                         924981.7
## FT003                               NA                               NA
## FT004                               NA                               NA
## FT005                        2058863.1                               NA
## FT006                               NA                               NA
##       x021_red_merlot_B_1_NEG_DDA.mzML x022_red_frappa_A_1_NEG_DDA.mzML
## FT001                        1721708.3                        1038064.2
## FT002                        1036225.4                        1173011.5
## FT003                         460387.9                         310784.4
## FT004                        1679054.1                         666971.4
## FT005                               NA                        1134783.9
## FT006                               NA                               NA
##       x023_wht_ptgrig_A_1_NEG_DDA.mzML x024_red_sangio_A_1_NEG_DDA.mzML
## FT001                               NA                         746794.4
## FT002                         667977.4                               NA
## FT003                               NA                        1315892.3
## FT004                               NA                        2223661.4
## FT005                               NA                               NA
## FT006                               NA                               NA
##       x025_red_lagrei_A_1_NEG_DDA.mzML x026_wht_chardo_C_1_NEG_DDA.mzML
## FT001                        2247568.5                               NA
## FT002                               NA                         743351.6
## FT003                         294771.2                               NA
## FT004                         629777.6                               NA
## FT005                               NA                         963538.4
## FT006                               NA                         291901.9
##       x028_X_QC_X_5_NEG_DDA.mzML x029_X_QC_X_6_NEG_DDA.mzML
## FT001                         NA                         NA
## FT002                   892491.9                   899920.7
## FT003                         NA                         NA
## FT004                         NA                         NA
## FT005                   847438.4                   791870.4
## FT006                   529113.8                   443991.4

Well … we see a lot of NAs there … Recalling what we discussed in the lecture, NAs can be there for two main reasons:

Anyway, xcms implement a clever strategy to try to fix, at least partially, the NAs. The function fillChromPeaks will take care of going back to the raw files and integrate the signal possibly present in the mz/rt region of each feature. If the peak was there and was missed by chance this will basically recover the lost signal.

raw_data_filled <- fillChromPeaks(raw_data)
## Defining peak areas for filling-in .... OK
## Start integrating peak areas from original files
## Requesting 146 peaks from x029_X_QC_X_6_NEG_DDA.mzML ... got 144.
## 
## Requesting 291 peaks from x012_wht_moscat_A_1_NEG_DDA.mzML ... got 154.
## Requesting 281 peaks from x013_wht_ptgrig_C_1_NEG_DDA.mzML ... got 153.
## Requesting 144 peaks from x015_X_QC_X_3_NEG_DDA.mzML ... got 140.
## Requesting 151 peaks from x016_X_QC_X_4_NEG_DDA.mzML ... got 149.
## Requesting 308 peaks from x017_wht_ptgrig_B_1_NEG_DDA.mzML ... got 186.
## 
## Requesting 144 peaks from x002_X_QC_X_1_NEG_DDA.mzML ... got 139.
## Requesting 133 peaks from x003_X_QC_X_2_NEG_DDA.mzML ... got 133.
## Requesting 240 peaks from x004_red_sangio_B_1_NEG_DDA.mzML ... got 203.
## Requesting 325 peaks from x005_red_ptnoir_A_1_NEG_DDA.mzML ... got 236.
## Requesting 201 peaks from x006_red_merlot_A_1_NEG_DDA.mzML ... got 173.
## 
## Requesting 230 peaks from x018_red_ptnoir_B_1_NEG_DDA.mzML ... got 192.
## Requesting 316 peaks from x019_wht_sauvig_A_1_NEG_DDA.mzML ... got 204.
## Requesting 299 peaks from x020_wht_gewurz_A_1_NEG_DDA.mzML ... got 158.
## Requesting 240 peaks from x021_red_merlot_B_1_NEG_DDA.mzML ... got 207.
## Requesting 234 peaks from x022_red_frappa_A_1_NEG_DDA.mzML ... got 189.
## 
## Requesting 257 peaks from x023_wht_ptgrig_A_1_NEG_DDA.mzML ... got 147.
## Requesting 323 peaks from x024_red_sangio_A_1_NEG_DDA.mzML ... got 239.
## Requesting 368 peaks from x025_red_lagrei_A_1_NEG_DDA.mzML ... got 193.
## Requesting 242 peaks from x026_wht_chardo_C_1_NEG_DDA.mzML ... got 147.
## Requesting 130 peaks from x028_X_QC_X_5_NEG_DDA.mzML ... got 123.
## 
## Requesting 296 peaks from x007_wht_vermen_A_1_NEG_DDA.mzML ... got 190.
## Requesting 234 peaks from x008_red_cannon_A_1_NEG_DDA.mzML ... got 201.
## Requesting 292 peaks from x009_wht_chardo_B_1_NEG_DDA.mzML ... got 181.
## Requesting 264 peaks from x010_wht_chardo_A_1_NEG_DDA.mzML ... got 144.
## Requesting 376 peaks from x011_red_lagrei_B_1_NEG_DDA.mzML ... got 208.
DM <- featureValues(raw_data_filled, value = "into") 
head(DM)
##       x002_X_QC_X_1_NEG_DDA.mzML x003_X_QC_X_2_NEG_DDA.mzML
## FT001                   360508.9                  353756.56
## FT002                   986147.4                  975746.51
## FT003                   112981.2                   23360.64
## FT004                   527294.7                  588971.93
## FT005                   947277.0                  802055.38
## FT006                   438418.3                  401059.72
##       x004_red_sangio_B_1_NEG_DDA.mzML x005_red_ptnoir_A_1_NEG_DDA.mzML
## FT001                         716179.8                       1131380.07
## FT002                         708724.8                        138880.65
## FT003                         475746.8                         69369.56
## FT004                         981039.5                        344743.51
## FT005                        1505677.8                        423297.72
## FT006                         614215.3                        164831.39
##       x006_red_merlot_A_1_NEG_DDA.mzML x007_wht_vermen_A_1_NEG_DDA.mzML
## FT001                        1035399.5                               NA
## FT002                         987357.0                         454742.3
## FT003                         717797.0                               NA
## FT004                        1070248.7                               NA
## FT005                          66347.0                        1066122.2
## FT006                         289532.3                         398657.3
##       x008_red_cannon_A_1_NEG_DDA.mzML x009_wht_chardo_B_1_NEG_DDA.mzML
## FT001                         110110.3                               NA
## FT002                         735192.5                         308628.3
## FT003                         332599.6                               NA
## FT004                         685215.9                               NA
## FT005                         526072.9                        1280785.3
## FT006                         142918.2                         273601.2
##       x010_wht_chardo_A_1_NEG_DDA.mzML x011_red_lagrei_B_1_NEG_DDA.mzML
## FT001                               NA                       1674083.64
## FT002                         631526.5                         88090.12
## FT003                               NA                        266367.13
## FT004                               NA                        726500.53
## FT005                        1409850.9                         24040.09
## FT006                         249928.5                               NA
##       x012_wht_moscat_A_1_NEG_DDA.mzML x013_wht_ptgrig_C_1_NEG_DDA.mzML
## FT001                               NA                               NA
## FT002                          1119334                         724985.1
## FT003                               NA                               NA
## FT004                               NA                               NA
## FT005                          1324338                         900748.1
## FT006                               NA                         139998.1
##       x015_X_QC_X_3_NEG_DDA.mzML x016_X_QC_X_4_NEG_DDA.mzML
## FT001                  579689.22                  273061.99
## FT002                  575473.90                 1127542.49
## FT003                   43828.02                   77739.66
## FT004                  330076.75                  525037.37
## FT005                  952594.73                  794963.58
## FT006                  493059.49                  513929.76
##       x017_wht_ptgrig_B_1_NEG_DDA.mzML x018_red_ptnoir_B_1_NEG_DDA.mzML
## FT001                               NA                         389920.3
## FT002                         759701.4                        1010649.1
## FT003                               NA                         510139.4
## FT004                               NA                        1893196.4
## FT005                        1751762.1                        1680198.6
## FT006                         939508.5                         627432.0
##       x019_wht_sauvig_A_1_NEG_DDA.mzML x020_wht_gewurz_A_1_NEG_DDA.mzML
## FT001                               NA                               NA
## FT002                         895189.3                         924981.7
## FT003                               NA                               NA
## FT004                               NA                               NA
## FT005                        2058863.1                               NA
## FT006                         536513.6                               NA
##       x021_red_merlot_B_1_NEG_DDA.mzML x022_red_frappa_A_1_NEG_DDA.mzML
## FT001                       1721708.27                        1038064.2
## FT002                       1036225.43                        1173011.5
## FT003                        460387.90                         310784.4
## FT004                       1679054.14                         666971.4
## FT005                        120163.61                        1134783.9
## FT006                         88149.44                         234804.2
##       x023_wht_ptgrig_A_1_NEG_DDA.mzML x024_red_sangio_A_1_NEG_DDA.mzML
## FT001                               NA                         746794.4
## FT002                        667977.44                         439009.6
## FT003                               NA                        1315892.3
## FT004                               NA                        2223661.4
## FT005                        130263.78                         304219.6
## FT006                         74391.78                         288818.9
##       x025_red_lagrei_A_1_NEG_DDA.mzML x026_wht_chardo_C_1_NEG_DDA.mzML
## FT001                        2247568.5                               NA
## FT002                         127789.9                         743351.6
## FT003                         294771.2                               NA
## FT004                         629777.6                               NA
## FT005                               NA                         963538.4
## FT006                               NA                         291901.9
##       x028_X_QC_X_5_NEG_DDA.mzML x029_X_QC_X_6_NEG_DDA.mzML
## FT001                   399528.8                   304736.0
## FT002                   892491.9                   899920.7
## FT003                   121386.2                   103181.5
## FT004                   422484.7                   485913.5
## FT005                   847438.4                   791870.4
## FT006                   529113.8                   443991.4

The definition of each feature can be extracted with a specific function:

feat <- featureDefinitions(raw_data_filled)
feat
## DataFrame with 734 rows and 12 columns
##           mzmed     mzmin     mzmax     rtmed     rtmin     rtmax    npeaks
##       <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> <numeric>
## FT001   56.5699   56.5698   56.5699  274.4321  273.0029  275.6861         8
## FT002   59.0140   59.0139   59.0141   52.5710   51.2949   53.7408        17
## FT003   65.6779   65.6779   65.6780   61.2852   60.2421   68.9642        10
## FT004   65.6779   65.6779   65.6779   79.8001   78.4873   80.2757         9
## FT005   68.4565   68.4564   68.4565  182.2209  179.7875  183.5496        17
## ...         ...       ...       ...       ...       ...       ...       ...
## FT730   657.090   657.090   657.091   144.041   138.149   147.620        16
## FT731   657.090   657.090   657.091   252.483   250.670   253.659        12
## FT732   657.091   657.090   657.091   219.358   216.425   221.860        10
## FT733   657.090   657.090   657.091   132.686   125.768   137.218        12
## FT734   879.164   879.163   879.165   212.744   211.804   214.443        13
##             red       wht         X            peakidx  ms_level
##       <numeric> <numeric> <numeric>             <list> <integer>
## FT001         8         0         0 1875,2539,3298,...         1
## FT002         6         6         5  405, 730,1460,...         1
## FT003         9         0         0 1546,2883,4377,...         1
## FT004         9         0         0 1545,2882,4376,...         1
## FT005         3         8         6  292,1010,1713,...         1
## ...         ...       ...       ...                ...       ...
## FT730         8         0         6  384,1095,1808,...         1
## FT731         6         0         6  412,1137,2511,...         1
## FT732         7         0         3  382,1096,1809,...         1
## FT733         7         0         4  383,1097,1810,...         1
## FT734         7         0         6  356,1075,1791,...         1

The situation improved, but it is not yet perfect.

We now save the output which will be used for the subsequent statistical analysis and compound annotation:

save(raw_data_filled, DM, feat, file = "processed_wines_data.RData")

Checking Feature chromatograms

A typical thing one wants to DO at some point in the analysis is to check if the chromatographic peaks of a really interesting feature are really there …

In order to do that xcms provides a really handy function:

ft_chr1 <- featureChromatograms(raw_data, 
                                features = "FT005", 
                                expandRt = 15, 
                                filled = FALSE)

Now we plot it highlighting the integrated areas and the class of the samples:

sample_colors <- group_colors[raw_data$color]
plot(ft_chr1, col = group_colors[raw_data$color],
     peakBg = sample_colors[chromPeaks(ft_chr1)[, "sample"]])

That can be used to spot problems of integration, and, also, if a biomarker is really a biomarker ;-)

DIY

Feature Quality Assessment

As we stressed along the full lecture, the best way to validate the outcomes of your analysis is to go back to the raw data and inspect the extracted ion traces. However it would be useful to get an overall feedback on “quality” of each feature.

xcms already implements some useful tool to do that:

head(featureSummary(raw_data))
##       count     perc multi_count multi_perc       rsd
## FT001     8 30.76923           0    0.00000 0.4176693
## FT002    17 65.38462           0    0.00000 0.1798341
## FT003     9 34.61538           1   11.11111 0.6343434
## FT004     9 34.61538           0    0.00000 0.5146304
## FT005    17 65.38462           0    0.00000 0.3213700
## FT006    10 38.46154           0    0.00000 0.3302743

Here we see:

This can be also split by sample class:

sample_vs_qc <- ifelse(raw_data$variety == "QC","QC","S")

featureSummary(raw_data, group = sample_vs_qc, skipFilled = FALSE) %>% 
  as_tibble() %>% 
  arrange(desc(QC_rsd))
## # A tibble: 734 × 15
##    count  perc multi_count multi_perc   rsd QC_count QC_perc QC_multi_count
##    <dbl> <dbl>       <dbl>      <dbl> <dbl>    <dbl>   <dbl>          <dbl>
##  1    15  57.7           2       13.3 0.907        4    66.7              0
##  2    18  69.2           4       22.2 0.928        5    83.3              1
##  3    12  46.2           3       25   0.883        4    66.7              1
##  4    15  57.7           3       20   0.693        4    66.7              1
##  5    15  57.7           3       20   0.531        6   100                1
##  6    20  76.9          13       65   0.543        4    66.7              4
##  7    14  53.8           2       14.3 0.970        4    66.7              0
##  8     9  34.6           1       11.1 0.621        4    66.7              1
##  9    26 100            25       96.2 0.490        6   100                6
## 10    12  46.2           0        0   0.577        5    83.3              0
## # ℹ 724 more rows
## # ℹ 7 more variables: QC_multi_perc <dbl>, QC_rsd <dbl>, S_count <dbl>,
## #   S_perc <dbl>, S_multi_count <dbl>, S_multi_perc <dbl>, S_rsd <dbl>

This useful to filter features with higher variability in the QC (more than in the samples). But …