
Data Retrieval and Utility Workflows
Adam Mattsson
2026-04-28
data_retrieval_and_utility_workflows.RmdIntroduction
This vignette demonstrates how to efficiently retrieve, filter, and summarize classification results using LundTaxR’s utility functions. After classifying samples, you often need to extract specific subsets, order samples for visualization, or compute summary metrics for downstream analysis. LundTaxR provides a suite of helper functions to streamline these common tasks.
What’s Covered
In this vignette, you’ll learn how to:
-
Extract subsets of predictions for specific sample
groups using
get_prediction_subset -
Order samples based on subtype, score, or other
criteria with
get_sample_order -
Compute and interpret subtype metrics using
get_subtype_metricsfor summary statistics and quality control
Each section includes practical code examples that you can adapt to your own data and workflows.
1. Extracting Prediction Subsets with
get_prediction_subset
After classifying your samples, you may want to focus your analysis
on a specific subset of samples—such as those belonging to a particular
group or cohort. The get_prediction_subset function is
designed to help you do just that: it extracts only the relevant samples
from all components of your prediction results, whether those components
are data frames or named vectors.
You can specify the samples to keep either by providing a vector of sample IDs, or by passing a metadata data frame that contains the desired samples (the metadata must contain a column with valid sample Ids, typically named “sample_id”). The function will return a new predictions list for the subset of samples specified.
Example: Subsetting by Sample IDs
Suppose you want to examine only a handful of samples from your classification results:
# Run the classifier (if not already done)
data("sjodahl_2017")
data("sjodahl_2017_meta")
results <- classify_samples(
this_data = sjodahl_2017,
include_data = TRUE,
verbose = FALSE
)
# Example 1: Select a few sample IDs
selected_samples <- head(sjodahl_2017_meta$sample_id)
# Subset the results to just these samples
subset_results <- get_prediction_subset(
these_predictions = results,
these_sample_ids = selected_samples
)
# View the subsetted data
head(subset_results$data)
#> 1.CEL 2.CEL 3.CEL 4.CEL 5.CEL 6.CEL
#> A1CF 4.248274 4.153923 4.186689 4.877813 4.106269 5.278318
#> A2M 8.348800 7.969504 10.755738 8.467495 8.979222 9.520587
#> A2ML1 6.694896 4.442973 8.871067 4.392010 7.685045 4.493648
#> A4GALT 7.255671 6.337239 6.925670 6.239185 6.032115 6.539985
#> A4GNT 3.740418 3.830598 3.999331 3.813662 3.718752 3.567144
#> AAAS 6.837006 7.525639 6.778506 6.658134 7.354926 6.611625
head(subset_results$subtype_scores)
#> Uro UroA UroB UroC GU BaSq Mes ScNE
#> 1.CEL 0.9924 0.9350 0.0048 0.0602 0.0072 0.0004 0.0000 0.0000
#> 2.CEL 0.0016 NA NA NA 0.0052 0.0054 0.9804 0.0074
#> 3.CEL 0.0682 NA NA NA 0.7754 0.0834 0.0390 0.0340
#> 4.CEL 0.9930 0.9334 0.0028 0.0638 0.0066 0.0004 0.0000 0.0000
#> 5.CEL 0.9808 0.0058 0.9878 0.0064 0.0076 0.0090 0.0006 0.0020
#> 6.CEL 0.0082 NA NA NA 0.9890 0.0002 0.0004 0.0022
#> prediction_delta_5_class prediction_delta_7_class
#> 1.CEL 0.9852 0.8748
#> 2.CEL 0.9730 NA
#> 3.CEL 0.6920 NA
#> 4.CEL 0.9864 0.8696
#> 5.CEL 0.9718 0.9814
#> 6.CEL 0.9808 NA
#> prediction_delta_collapsed
#> 1.CEL 0.8748
#> 2.CEL 0.9730
#> 3.CEL 0.6920
#> 4.CEL 0.8696
#> 5.CEL 0.9814
#> 6.CEL 0.9808
head(subset_results$predictions_5classes)
#> 1.CEL 2.CEL 3.CEL 4.CEL 5.CEL 6.CEL
#> "Uro" "Mes" "GU" "Uro" "Uro" "GU"
# Example 2: Using a metadata subset to the sample IDs of interest
metadata_sub = sjodahl_2017_meta %>% filter(turb_cis == 1)
# Subset the results to the samples in the filtered metadata
subset_results_meta <- get_prediction_subset(
these_predictions = results,
these_samples_metadata = metadata_sub
)
# View the subset prediction results
head(subset_results_meta$subtype_scores)
#> Uro UroA UroB UroC GU BaSq Mes ScNE
#> 10.CEL 0.9986 0.1270 0.0136 0.8594 0.0014 0.0000 0.0000 0.0000
#> 19.CEL 0.0058 NA NA NA 0.0116 0.0996 0.8772 0.0058
#> 21.CEL 0.9896 0.0212 0.9596 0.0192 0.0064 0.0026 0.0006 0.0008
#> 30.CEL 0.0018 NA NA NA 0.9974 0.0002 0.0000 0.0006
#> 43.CEL 0.9996 0.0642 0.8204 0.1154 0.0004 0.0000 0.0000 0.0000
#> 48.CEL 0.1608 NA NA NA 0.0208 0.8112 0.0040 0.0032
#> prediction_delta_5_class prediction_delta_7_class
#> 10.CEL 0.9972 0.7324
#> 19.CEL 0.7776 NA
#> 21.CEL 0.9832 0.9384
#> 30.CEL 0.9956 NA
#> 43.CEL 0.9992 0.7050
#> 48.CEL 0.6504 NA
#> prediction_delta_collapsed
#> 10.CEL 0.7324
#> 19.CEL 0.7776
#> 21.CEL 0.9384
#> 30.CEL 0.9956
#> 43.CEL 0.7050
#> 48.CEL 0.6504Example: Subsetting by Metadata
Alternatively, you can subset your results using a metadata data frame. This is useful if you have filtered your metadata for a specific group (e.g., only tumor samples, or only a certain clinical stage):
# Take a subset of the metadata
meta_subset <- head(sjodahl_2017_meta)
# Subset the results using the metadata
subset_results_meta <- get_prediction_subset(
these_predictions = results,
these_samples_metadata = meta_subset,
samples_rownames = FALSE
)
# View the subsetted data
head(subset_results_meta$data)
#> 1.CEL 2.CEL 3.CEL 4.CEL 5.CEL 6.CEL
#> A1CF 4.248274 4.153923 4.186689 4.877813 4.106269 5.278318
#> A2M 8.348800 7.969504 10.755738 8.467495 8.979222 9.520587
#> A2ML1 6.694896 4.442973 8.871067 4.392010 7.685045 4.493648
#> A4GALT 7.255671 6.337239 6.925670 6.239185 6.032115 6.539985
#> A4GNT 3.740418 3.830598 3.999331 3.813662 3.718752 3.567144
#> AAAS 6.837006 7.525639 6.778506 6.658134 7.354926 6.6116252. Ordering Samples by Proliferation Score with
get_sample_order
When visualizing or analyzing your classification results, it’s often
helpful to arrange samples in a biologically meaningful order. The
get_sample_order function provides a convenient way to sort
your samples based on their proliferation score, specifically the
late/early cell cycle sugnature ratio. Note, this is the implemented
sample order that is shown in the
plot_classification_heatmap.
This function is especially useful for downstream plotting, as it returns a vector of sample names ordered by their proliferation status. You can use this order to consistently arrange samples in heatmaps or other visualizations.
Example: Ordering by Late/Early Cell Cycle Signature Ratio
To use get_sample_order, make sure you ran
classify_samples with include_data = TRUE so
the expression data is available:
# Get the sample order based on late/early ratio (default)
ordered_samples <- get_sample_order(expr_data = results$data)
#> [1] 158 194 142 171 43 76 235 83 160 31 68 237 232 187 22 130 259 163
#> [19] 134 245 55 168 131 234 99 47 161 61 137 7 85 236 199 28 264 175
#> [37] 254 202 266 13 94 184 3 253 231 26 54 164 95 103 178 179 221 223
#> [55] 73 224 132 113 46 49 102 166 241 112 97 100 41 167 107 249 239 15
#> [73] 220 91 9 4 114 242 64 36 119 62 233 56 243 29 98 191 246 225
#> [91] 247 205 63 222 240 206 227 156 14 79 21 252 58 190 65 1 248 145
#> [109] 117 125 151 200 251 101 155 172 215 51 212 165 78 69 77 162 75 20
#> [127] 218 81 229 24 116 244 126 170 108 105 123 60 141 136 256 133 80 111
#> [145] 138 23 19 48 208 93 159 188 72 216 12 217 192 25 209 147 182 5
#> [163] 181 122 110 18 230 92 27 124 86 135 257 228 152 66 71 183 118 10
#> [181] 204 44 50 121 57 37 250 186 40 197 153 115 219 203 89 30 177 90
#> [199] 96 139 143 42 201 144 11 106 70 176 150 260 154 6 169 238 185 193
#> [217] 207 180 87 33 173 16 149 104 262 195 35 127 258 109 129 59 261 32
#> [235] 52 211 213 148 263 82 38 120 2 45 53 84 74 196 140 174 267 146
#> [253] 39 67 265 88 17 210 255 214 189 226 128 8 34 157 198
head(ordered_samples)
#> [1] 158 194 142 171 43 76
# If you want the actual late/early ratio values instead of the order:
late_early_ratios <- get_sample_order(expr_data = results$data, return_this = "late_early")
#> [1] 158 194 142 171 43 76 235 83 160 31 68 237 232 187 22 130 259 163
#> [19] 134 245 55 168 131 234 99 47 161 61 137 7 85 236 199 28 264 175
#> [37] 254 202 266 13 94 184 3 253 231 26 54 164 95 103 178 179 221 223
#> [55] 73 224 132 113 46 49 102 166 241 112 97 100 41 167 107 249 239 15
#> [73] 220 91 9 4 114 242 64 36 119 62 233 56 243 29 98 191 246 225
#> [91] 247 205 63 222 240 206 227 156 14 79 21 252 58 190 65 1 248 145
#> [109] 117 125 151 200 251 101 155 172 215 51 212 165 78 69 77 162 75 20
#> [127] 218 81 229 24 116 244 126 170 108 105 123 60 141 136 256 133 80 111
#> [145] 138 23 19 48 208 93 159 188 72 216 12 217 192 25 209 147 182 5
#> [163] 181 122 110 18 230 92 27 124 86 135 257 228 152 66 71 183 118 10
#> [181] 204 44 50 121 57 37 250 186 40 197 153 115 219 203 89 30 177 90
#> [199] 96 139 143 42 201 144 11 106 70 176 150 260 154 6 169 238 185 193
#> [217] 207 180 87 33 173 16 149 104 262 195 35 127 258 109 129 59 261 32
#> [235] 52 211 213 148 263 82 38 120 2 45 53 84 74 196 140 174 267 146
#> [253] 39 67 265 88 17 210 255 214 189 226 128 8 34 157 198
head(late_early_ratios)
#> late_early_ratio
#> 1.CEL -0.85912360
#> 2.CEL 0.08838817
#> 3.CEL -1.35966918
#> 4.CEL -1.14506690
#> 5.CEL -0.50815862
#> 6.CEL -0.18543936This ordering can be used directly in plotting functions or to structure your data for further analysis, ensuring that samples are consistently arranged by their proliferation characteristics.
3. Summarizing Subtype Metrics with
get_subtype_metrics
Understanding how clinical or experimental variables are distributed
across molecular subtypes is a key part of downstream analysis. The
get_subtype_metrics function makes it easy to tabulate and
summarize metadata variables (such as sex, stage, survival events, or
other annotations) by subtype classification.
This function works by matching sample IDs between your metadata and prediction results, then counting the number of samples for each subtype and each level of your chosen metadata variable. You can focus on a specific value (e.g., only males, or only events) or get a full breakdown for all levels.
Example: Counting Events by Subtype
Suppose you want to see how many overall survival events occurred in each subtype:
# Run the classifier if not already done
results <- classify_samples(
this_data = sjodahl_2017,
include_data = TRUE,
verbose = FALSE
)
# Tabulate survival events (e.g., "surv_os_event" column)
metrics_events <- get_subtype_metrics(
these_predictions = results,
this_metadata = sjodahl_2017_meta,
this_metadata_variable = "surv_os_event",
factor_level = 1
)
#set subtype order for table output
desired_order <- c("Uro", "GU", "BaSq", "Mes", "ScNE")
#print table
metrics_events %>%
mutate(prediction = factor(prediction, levels = desired_order)) %>%
arrange(prediction) %>%
knitr::kable()| prediction | total_samples | surv_os_event_1 |
|---|---|---|
| Uro | 121 | 58 |
| GU | 54 | 29 |
| BaSq | 56 | 30 |
| Mes | 16 | 11 |
| ScNE | 20 | 9 |
Example: Summarizing Sex Distribution
You can also use this function to summarize categorical variables, such as sex:
metrics_gender <- get_subtype_metrics(
these_predictions = results,
this_metadata = sjodahl_2017_meta,
this_metadata_variable = "gender",
factor_level = "Male"
)
desired_order <- c("Uro", "GU", "BaSq", "Mes", "ScNE")
metrics_gender %>%
mutate(prediction = factor(prediction, levels = desired_order)) %>%
arrange(prediction) %>%
knitr::kable()| prediction | total_samples | gender_Male |
|---|---|---|
| Uro | 121 | 95 |
| GU | 54 | 42 |
| BaSq | 56 | 41 |
| Mes | 16 | 13 |
| ScNE | 20 | 14 |
This approach helps you quickly assess the distribution of key variables across subtypes, supporting both quality control and hypothesis generation in your analyses.