library(readxl)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(janitor)
##
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
proteomics_raw <- read_excel("Copy_of_Proteomics_data_original_1.xlsx",
sheet = "proteins_imputed_80 percent_V3") %>%
clean_names()
dim(proteomics_raw)
## [1] 178 1224
proteomics_raw %>% tabyl(pathology)
## pathology n percent
## Bmass 62 0.3483146
## HC 35 0.1966292
## PDAC 81 0.4550562
Proteomics uses three pathology categories (Bmass, HC, PDAC) rather than the six categories found in the clinical data (BBP, RPC, HC, LAPC, MPC, CP). This suggests a coarser classification, likely collapsing benign groups into “Bmass” and cancer subtypes into “PDAC” — the exact mapping needs to be confirmed once the crosswalk file is available.
proteomics_raw %>%
select(file_name, pathology, linked_id) %>%
slice_head(n = 15)
## # A tibble: 15 × 3
## file_name pathology linked_id
## <chr> <chr> <chr>
## 1 B1_S2-D3_1_3370.d PDAC P067
## 2 B1_S2-D4_1_3396.d PDAC P068
## 3 B2_S3-D11_1_3463.d PDAC P069
## 4 B2_S3-D12_1_3447.d PDAC P070
## 5 B1_S2-D5_1_3403.d PDAC P072
## 6 B2_S3-E1_1_3480.d PDAC P073
## 7 B2_S3-E2_1_3495.d PDAC P074
## 8 B2_S3-E3_1_3457.d PDAC P075
## 9 B1_S2-D7_1_3416.d PDAC P076
## 10 B3_S4-D10_1_3520.d PDAC P077
## 11 B3_S4-D11_1_3518.d PDAC P078
## 12 B1_S2-D8_1_3377.d PDAC P079
## 13 B3_S4-D12_1_3513.d PDAC P081
## 14 B3_S4-E1_1_3528.d PDAC P082
## 15 B3_S4-E2_1_3546.d PDAC P083
file_name contains raw mass spectrometer output
filenames, not diagnostic codes — this is expected metadata about the
instrument run, not a data quality issue. pathology and
linked_id both contain proper, expected values.
proteomics_raw %>%
select(-file_name, -pathology, -linked_id) %>%
summarise(across(everything(), ~ sum(is.na(.)))) %>%
rowSums()
## [1] 0
Zero missing values across all 1221 proteins, consistent with this dataset already being imputed (per the sheet name, “proteins_imputed_80 percent_V3”).
proteomics_raw %>%
count(linked_id) %>%
filter(n > 1)
## # A tibble: 3 × 2
## linked_id n
## <chr> <int>
## 1 HC14 2
## 2 P067 2
## 3 P070 2
proteomics_raw %>%
filter(linked_id %in% c("HC14", "P067", "P070")) %>%
select(file_name, pathology, linked_id, a1bg, a2m)
## # A tibble: 6 × 5
## file_name pathology linked_id a1bg a2m
## <chr> <chr> <chr> <dbl> <dbl>
## 1 B1_S2-D3_1_3370.d PDAC P067 8664. 167513.
## 2 B2_S3-D12_1_3447.d PDAC P070 9282. 113251.
## 3 B1_S2-A12_1_3376.d PDAC P067 13383. 348350.
## 4 B2_S3-A8_1_3454.d PDAC P070 6233. 199897.
## 5 B1_S2-D11_1_3424.d HC HC14 1682. 63159.
## 6 B2_S3-E9_1_3450.d HC HC14 3567. 305892.
Three patients (HC14, P067, P070) each have two technical replicate
runs, confirmed by different file_name values per pair.
Replicate values agree reasonably well for P067 and P070 (~1.5-2x
spread), but HC14 shows a larger ~5-fold difference between runs.
Note: replicates are averaged below as a provisional approach; this is pending confirmation from the supervisor, particularly for HC14, where the 5-fold spread is notably larger than the other two patients.
proteomics_clean <- proteomics_raw %>%
group_by(linked_id, pathology) %>%
summarise(across(where(is.numeric), mean), .groups = "drop")
dim(proteomics_clean)
## [1] 175 1223
protein_values <- proteomics_clean %>% select(-linked_id, -pathology)
range(protein_values, na.rm = TRUE)
## [1] 2.080078e+00 2.756291e+07
Range spans roughly 2 to 27.6 million — all positive, no corrupted values, but spanning nearly seven orders of magnitude. This is expected for proteomics abundance data and confirms a log-transformation step will be needed before any statistical modelling (PCA, Cox-LASSO).
saveRDS(proteomics_clean, "proteomics_clean.rds")
list.files(pattern = ".rds")
## [1] "clinical_clean.rds" "proteomics_clean.rds"