Function for fitting four-parameter dose response curves for each group (precursor, peptide or protein). In addition it can annotate data based on completeness, the completeness distribution and statistical testing using ANOVA. Filtering by the function is only performed based on completeness if selected.
fit_drc_4p(
data,
sample,
grouping,
response,
dose,
filter = "post",
replicate_completeness = 0.7,
condition_completeness = 0.5,
n_replicate_completeness = NULL,
n_condition_completeness = NULL,
complete_doses = NULL,
anova_cutoff = 0.05,
correlation_cutoff = 0.8,
log_logarithmic = TRUE,
include_models = FALSE,
retain_columns = NULL
)
a data frame that contains at least the input variables.
a character column in the data
data frame that contains the sample names.
a character column in the data
data frame that contains the precursor,
peptide or protein identifiers.
a numeric column in the data
data frame that contains the response
values, e.g. log2 transformed intensities.
a numeric column in the data
data frame that contains the dose values, e.g.
the treatment concentrations.
a character value that can either be "pre"
, "post"
or "none"
. The data is
annotated for completeness, ANOVA significance and the completeness distribution along
the doses ("pre"
and "post"
). The combined output of this filtering step can be found in
the passed_filter
column and depends on the cutoffs provided to the function. Note that this
is only an annotation and nothing is removed from the output. If "pre"
is selected then, in
addition to the annotation, the data is filtered for completeness based on the condition completeness
prior to the curve fitting and ANOVA calculation and p-value adjustment. This has the benefit that less
curves need to be fitted and that the ANOVA p-value adjustment is done only on the relevant set of tests.
If "none"
is selected the data will be neither annotated nor filtered.
please use n_replicate_completeness
instead.
A numeric value which similar to completenss_MAR
of the
assign_missingness
function sets a threshold for the completeness of data. In contrast
to assign_missingness
it only determines the completeness for one condition and not the
comparison of two conditions. The threshold is used to calculate a minimal degree of data
completeness. The value provided to this argument has to be between 0 and 1, default is 0.7.
It is multiplied with the number of replicates and then adjusted downward. The resulting number
is the minimal number of observations that a condition needs to have to be considered "complete
enough" for the condition_completeness
argument.
please use n_condition_completeness
instead.
A numeric value which determines how many conditions need to at
least fulfill the "complete enough" criteria set with replicate_completeness
. The
value provided to this argument has to be between 0 and 1, default is 0.5. It is multiplied with
the number of conditions and then adjusted downward. The resulting number is the minimal number
of conditions that need to fulfill the replicate_completeness
argument for a peptide to
pass the filtering.
a numeric value that defines the minimal number of observations that a
condition (concentration) needs to have to be considered "complete enough" for the n_condition_completeness
argument. E.g. if each concentration has 4 replicates this argument could be set to 3 to allow for one
replicate to be missing for the completeness criteria.
a numeric value that defines the minimal number
of conditions that need to fulfill the n_replicate_completeness
argument for a feature to
pass the filtering. E.g. if an experiment has 12 concentrations, this argument could be set
to 6 to define that at least 6 of 12 concentrations need to make the replicate completeness cutoff.
an optional numeric vector that supplies all the actually used doses (concentrations) to the function. Usually the function extracts this information from the supplied data. However, for incomplete datasets the total number of assumed doses might be wrong. Therefore, it becomes important to provide this argument when the dataset is small and potentially incomplete. This information is only used for the missing not at random (MNAR) estimations.
a numeric value that specifies the ANOVA adjusted p-value cutoff used for
data filtering. Any fits with an adjusted ANOVA p-value bellow the cutoff will be considered
for scoring. The default is 0.05
.
a numeric value that specifies the correlation cutoff used for data filtering. Any fits with a correlation above the cutoff will be considered for scoring.
a logical value that indicates if a logarithmic or log-logarithmic model is fitted. If response values form a symmetric curve for non-log transformed dose values, a logarithmic model instead of a log-logarithmic model should be used. Usually biological dose response data has a log-logarithmic distribution, which is the reason this is the default. Log-logarithmic models are symmetric if dose values are log transformed.
a logical value that indicates if model fit objects should be exported. These are usually very large and not necessary for further analysis.
a vector that specifies columns that should be retained from the input
data frame. Default is not retaining additional columns retain_columns = NULL
. Specific
columns can be retained by providing their names (not in quotations marks, just like other
column names, but in a vector).
If include_models = FALSE
a data frame is returned that contains correlations
of predicted to measured values as a measure of the goodness of the curve fit, an associated
p-value and the four parameters of the model for each group. Furthermore, input data for plots
is returned in the columns plot_curve
(curve and confidence interval) and plot_points
(measured points). If include_models = TURE
, a list is returned that contains:
fit_objects
: The fit objects of type drc
for each group.
correlations
: The correlation data frame described above
If data filtering options are selected, data is annotated based on multiple criteria.
If "post"
is selected the data is annotated based on completeness, the completeness distribution, the
adjusted ANOVA p-value cutoff and a correlation cutoff. Completeness of features is determined based on
the n_replicate_completeness
and n_condition_completeness
arguments. The completeness distribution determines
if there is a distribution of not random missingness of data along the dose. For this it is checked if half of a
features values (+/-1 value) pass the replicate completeness criteria and half do not pass it. In order to fall into
this category, the values that fulfill the completeness cutoff and the ones that do not fulfill it
need to be consecutive, meaning located next to each other based on their concentration values. Furthermore,
the values that do not pass the completeness cutoff need to be lower in intensity. Lastly, the difference
between the two groups is tested for statistical significance using a Welch's t-test and a
cutoff of p <= 0.1 (we want to mainly discard curves that falsely fit the other criteria but that
have clearly non-significant differences in mean). This allows curves to be considered that have
missing values in half of their observations due to a decrease in intensity. It can be thought
of as conditions that are missing not at random (MNAR). It is often the case that those entities
do not have a significant p-value since half of their conditions are not considered due to data
missingness. The ANOVA test is performed on the features by concentration. If it is significant it is
likely that there is some response. However, this test would also be significant even if there is one
outlier concentration so it should only be used only in combination with other cutoffs to determine
if a feature is significant. The passed_filter
column is TRUE
for all the
features that pass the above mentioned criteria and that have a correlation greater than the cutoff
(default is 0.8) and the adjusted ANOVA p-value below the cutoff (default is 0.05).
The final list is ranked based on a score calculated on entities that pass the filter.
The score is the negative log10 of the adjusted ANOVA p-value scaled between 0 and 1 and the
correlation scaled between 0 and 1 summed up and divided by 2. Thus, the highest score an
entity can have is 1 with both the highest correlation and adjusted p-value. The rank is
corresponding to this score. Please note, that entities with MNAR conditions might have a
lower score due to the missing or non-significant ANOVA p-value. If no score could be calculated
the usual way these cases receive a score of 0. You should have a look at curves that are TRUE
for dose_MNAR
in more detail.
If the "pre"
option is selected for the filter
argument then the data is filtered for completeness
prior to curve fitting and the ANOVA test. Otherwise annotation is performed exactly as mentioned above.
We recommend the "pre"
option because it leaves you with not only the likely hits of your treatment, but
also with rather high confidence true negative results. This is because the filtered data has a high
degree of completeness making it unlikely that a real dose-response curve is missed due to data missingness.
Please note that in general, curves are only fitted if there are at least 5 conditions with data points present to ensure that there is potential for a good curve fit. This is done independent of the selected filtering option.
# \donttest{
# Load libraries
library(dplyr)
set.seed(123) # Makes example reproducible
# Create example data
data <- create_synthetic_data(
n_proteins = 2,
frac_change = 1,
n_replicates = 3,
n_conditions = 8,
method = "dose_response",
concentrations = c(0, 1, 10, 50, 100, 500, 1000, 5000),
additional_metadata = FALSE
)
# Perform dose response curve fit
drc_fit <- fit_drc_4p(
data = data,
sample = sample,
grouping = peptide,
response = peptide_intensity_missing,
dose = concentration,
n_replicate_completeness = 2,
n_condition_completeness = 5,
retain_columns = c(protein, change_peptide)
)
glimpse(drc_fit)
#> Rows: 45
#> Columns: 19
#> $ rank <dbl> 1, 2, 3, 4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
#> $ protein <chr> "protein_2", "protein_2", "protein_1", "protein_2", …
#> $ change_peptide <lgl> TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, F…
#> $ peptide <chr> "peptide_2_1", "peptide_2_3", "peptide_1_1", "peptid…
#> $ hill_coefficient <dbl> 2.226694e+00, 3.280387e+00, 1.949968e+00, -3.310549e…
#> $ min_model <dbl> 14.87823, 12.46267, 15.98823, 19.14721, 17.38748, 14…
#> $ max_model <dbl> 19.12933, 16.18910, 17.09804, 19.80934, 17.91095, 15…
#> $ ec_50 <dbl> 2.453723e+02, 1.417578e+02, 9.409896e+01, 6.293053e+…
#> $ correlation <dbl> 0.9986256, 0.9938863, 0.9668233, 0.9280152, 0.769849…
#> $ pval <dbl> 1.131609e-29, 8.423311e-15, 1.584077e-14, 6.625673e-…
#> $ plot_curve <list> [<tbl_df[100 x 4]>], [<tbl_df[100 x 4]>], [<tbl_df[…
#> $ plot_points <list> [<tbl_df[24 x 2]>], [<tbl_df[16 x 2]>], [<tbl_df[24…
#> $ enough_conditions <lgl> TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE…
#> $ dose_MNAR <lgl> FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALS…
#> $ anova_pval <dbl> 3.666126e-20, 1.471594e-05, 1.966510e-08, 2.858086e-…
#> $ anova_adj_pval <dbl> 1.613095e-18, 1.618753e-04, 4.326322e-07, 4.191860e-…
#> $ anova_significant <lgl> TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, F…
#> $ passed_filter <lgl> TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, …
#> $ score <dbl> 1.00000000, 0.46644068, 0.37320814, 0.05860592, NA, …
head(drc_fit, n = 10)
#> # A tibble: 10 × 19
#> rank protein change_peptide peptide hill_coefficient min_model max_model
#> <dbl> <chr> <lgl> <chr> <dbl> <dbl> <dbl>
#> 1 1 protein_2 TRUE peptide_… 2.23 14.9 19.1
#> 2 2 protein_2 TRUE peptide_… 3.28 12.5 16.2
#> 3 3 protein_1 TRUE peptide_… 1.95 16.0 17.1
#> 4 4 protein_2 TRUE peptide_… -3.31 19.1 19.8
#> 5 NA protein_1 TRUE peptide_… -4.81 17.4 17.9
#> 6 NA protein_1 FALSE peptide_… 2.07 14.8 15.2
#> 7 NA protein_1 FALSE peptide_… -0.0110 15.3 14.7
#> 8 NA protein_1 FALSE peptide_… 3.59 16.8 17.2
#> 9 NA protein_1 FALSE peptide_… -0.0000174 16.1 15.4
#> 10 NA protein_1 FALSE peptide_… -1.32 16.2 16.5
#> # ℹ 12 more variables: ec_50 <dbl>, correlation <dbl>, pval <dbl>,
#> # plot_curve <list>, plot_points <list>, enough_conditions <lgl>,
#> # dose_MNAR <lgl>, anova_pval <dbl>, anova_adj_pval <dbl>,
#> # anova_significant <lgl>, passed_filter <lgl>, score <dbl>
# }