|
264 | 264 | #' @return data.table |
265 | 265 | #' @keywords internal |
266 | 266 | .removeOverlappingFeatures = function(input) { |
267 | | - fraction_keep = Fraction = NULL |
| 267 | + Fraction = NULL |
268 | 268 |
|
269 | 269 | if (data.table::uniqueN(input$Fraction) > 1) { |
270 | | - input[, fraction_keep := .getCorrectFraction(.SD), |
271 | | - by = "feature", |
272 | | - .SDcols = c("feature", "Fraction", "Run", "Intensity")] |
273 | | - input = input[Fraction == fraction_keep] |
274 | | - input = input[, !(colnames(input) == "fraction_keep"), with = FALSE] |
| 270 | + measurement_count = input[ |
| 271 | + !is.na(Intensity) & Intensity > 0, |
| 272 | + .(n_obs = uniqueN(Run)), |
| 273 | + by = .(feature, Fraction) |
| 274 | + ] |
| 275 | + measurement_count[, is_max := n_obs == max(n_obs), by = "feature"] |
| 276 | + max_fractions = measurement_count[(is_max)] |
| 277 | + |
| 278 | + fraction_map = .resolveFractionTies(input, max_fractions) |
| 279 | + input = input[fraction_map, on = .(feature, Fraction), nomatch = 0] |
275 | 280 | } |
276 | 281 | input |
277 | 282 | } |
278 | 283 |
|
279 | 284 |
|
280 | | -#' Get a name of fraction with the largest number of measurements or the largest |
281 | | -#' average intensity |
| 285 | +#' Resolve ties when multiple fractions share the maximum number of measurements |
| 286 | +#' for a given feature. In the case of a tie, the fraction with the highest |
| 287 | +#' mean intensity is selected. |
282 | 288 | #' @param input output of `MSstatsPreprocess` |
283 | | -#' @return character - label of the fraction that has most measurements or |
284 | | -#' highest mean intensity for a given feature |
| 289 | +#' @param max_fractions data.table of fractions that share the maximum number |
| 290 | +#' of unique runs per feature, as produced by `.removeOverlappingFeatures` |
| 291 | +#' @return data.table with columns `feature` and `Fraction`, containing one |
| 292 | +#' selected fraction per feature |
285 | 293 | #' @keywords internal |
286 | | -.getCorrectFraction = function(input) { |
287 | | - Intensity = Run = Fraction = NULL |
| 294 | +.resolveFractionTies = function(input, max_fractions) { |
| 295 | + tie_features = max_fractions[, .(n_ties = .N), by = "feature"][n_ties > 1, feature] |
288 | 296 |
|
289 | | - measurement_count = input[!is.na(Intensity) & Intensity > 0, |
290 | | - list(n_obs = data.table::uniqueN(Run)), |
291 | | - by = "Fraction"] |
292 | | - which_max_measurements = which(measurement_count$n_obs == max(measurement_count$n_obs)) |
293 | | - if (length(which_max_measurements) == 1L) { |
294 | | - return(unique(measurement_count$Fraction[which_max_measurements])) |
| 297 | + if (length(tie_features) > 0) { |
| 298 | + tied_fractions = max_fractions[feature %in% tie_features, .(feature, Fraction)] |
| 299 | + avg_abundance = input[ |
| 300 | + tied_fractions, on = .(feature, Fraction), nomatch = 0 |
| 301 | + ][!is.na(Intensity) & Intensity > 0, |
| 302 | + .(mean_abundance = mean(Intensity)), |
| 303 | + by = .(feature, Fraction)] |
| 304 | + best_tied = avg_abundance[, .SD[which.max(mean_abundance)], by = "feature"] |
| 305 | + best_simple = max_fractions[ |
| 306 | + !feature %in% tie_features, |
| 307 | + .(Fraction = Fraction[1]), |
| 308 | + by = "feature" |
| 309 | + ] |
| 310 | + rbind(best_simple[, .(feature, Fraction)], |
| 311 | + best_tied[, .(feature, Fraction)]) |
295 | 312 | } else { |
296 | | - input = input[Fraction %in% measurement_count$Fraction[which_max_measurements]] |
297 | | - average_abundance = input[!is.na(Intensity) & Intensity > 0, |
298 | | - list(mean_abundance = mean(Intensity)), |
299 | | - by = "Fraction"] |
300 | | - which_max_abundance = which.max(average_abundance$mean_abundance) |
301 | | - unique(average_abundance$Fraction[which_max_abundance]) |
| 313 | + max_fractions[, .(Fraction = Fraction[1]), by = "feature"] |
302 | 314 | } |
303 | 315 | } |
304 | 316 |
|
|
0 commit comments