# library(patchwork) library(bidsconvertr)
datatable_setting <- function(df) { DT::datatable( df, extensions = c('Scroller'), options = list( search = list(regex = TRUE), searchHighlight = TRUE, pageLength = 25, dom = 'Bfrtip', deferRender = TRUE, scrollY = 200, scroller = TRUE ), filter = 'top' ) } df_select_n <- function(df) { df <- df %>% select(session, BIDS_type, BIDS_sequence, relevant) %>% group_by(across(everything())) %>% count() %>% ungroup() # spread(. ,session, value = n) return(df) } df_select_n_group <- function(df) { df <- df %>% select(session, BIDS_type, BIDS_sequence, group, PatientSex, relevant) %>% filter(relevant == 1) %>% group_by(across(everything())) %>% count() %>% ungroup() return(df) } df_select_patient_info <- function(df){ df2 <- df %>% mutate(group = "all") df <- df %>% rbind(df2) %>% select(subject, session, group, PatientSex, PatientWeight, PatientBirthDate, AcquisitionDateTime) %>% mutate(AcquisitionDateTime = as.Date(AcquisitionDateTime), Age = time_length(difftime(AcquisitionDateTime, PatientBirthDate), "years") %>% round(digits = 2)) %>% unique() return(df) } plot_bar <- function(df){ p_relevant <- df %>% filter(relevant == 1) %>% # filter(BIDS_type == "anat") %>% ggplot(aes(x = BIDS_sequence, y = freq, fill = session)) + geom_bar(position="dodge", stat = "identity") + facet_grid(. ~ BIDS_type, scales = "free_x", space = "free_x") + theme(legend.position="top", axis.text.x = element_text(angle = 45, hjust=1)) + xlab("")+ ggtitle("Relevant Sequences") + ylab("Number of scans") df_irrelevant <- df %>% filter(relevant == 0) if(nrow(df_irrelevant > 0)){ p_irrelevant <- df %>% filter(relevant == 0) %>% ggplot(aes(x = BIDS_sequence, y =freq, fill = session)) + geom_bar(position="dodge", stat = "identity") + facet_grid(. ~ BIDS_type, scales = "free_x", space = "free_x") + theme(legend.position="none") + xlab("")+ ylab("Number of scans") + ggtitle("Irrelevant Sequences") p_relevant / p_irrelevant + plot_annotation( title = 'Sequence overview' ) & theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust=1), legend.position="none") } else { p_relevant + ggtitle("Sequence Overview") + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust=1), legend.position="none") } #ggplotly(p) %>% layout(margin = list(l = 100, r = 20, b = 50, t = 100)) } calculate_comp_subjects <- function(df, sessions) { df <- df %>% select(subject, session, group, BIDS_sequence, relevant) %>% filter(relevant == 1) %>% select(-relevant) %>% group_by(across(everything())) %>% count() %>% ungroup %>% spread(session, freq) %>% mutate("RatioCompleteSurveys" = rowSums(select(., contains("ses-")), na.rm = TRUE)/sessions) %>% group_by(subject) %>% mutate("RatioCompleteSubjects" = mean(RatioCompleteSurveys)) %>% ungroup() return(df) } show_settings <- function(df) { df <- df %>% select(-filename, -subject, -session, -level, -input_json, -BIDS_json, -sequence, -BIDS_sequence_ID, -SeriesDescription, -ProtocolName, -InstitutionalDepartmentName, -InstitutionName, -Manufacturer, -ManufacturersModelName, -MagneticFieldStrength, -Modality, -DeviceSerialNumber, -SoftwareVersions, -StationName) %>% select(-AcquisitionNumber, -ImageOrientationPatientDICOM, -ImageBIDS_type, -ProcedureStepDescription, # -AccessionNumber, -StudyID, -StudyInstanceUID, -SeriesNumber, -SeriesInstanceUID ) %>% select( -AcquisitionDateTime, -AcquisitionTime, -PatientBirthDate, -PatientID, -PatientSex, -PatientName, -PatientWeight, # -PhilipsRescaleSlope ) %>% mutate(across(where(is.numeric), round, digits = 2)) %>% group_by(across(everything())) %>% count() %>% ungroup() %>% select(BIDS_sequence, BIDS_type, n, group_BIDS, relevant, everything()) return(df) }
# debug converter_path = "C:/Science/bids_lab_talk/bids_bidirect_converter/" bids_path <- paste0(converter_path, "/bids/sourcedata") json_metadata <- paste0(converter_path, "/json_metadata.tsv") json_metadata <- "/Dokumente und Einstellungen/Niklas/Downloads/json_metadata.tsv" sequence_map <- "/Dokumente und Einstellungen/Niklas/Downloads/sequence_map.tsv" sequence_map <- paste0(converter_path, "/sequence_map.tsv") # original bids_path <- paste0(params$converter_path, "/bids/sourcedata") json_metadata <- paste0(params$converter_path, "/json_metadata.tsv") sequence_map <- paste0(params$converter_path, "/sequence_map.tsv") # create paths dataset_description <- paste0(bids_path, "/dataset_description.json") dataset_readme <- paste0(bids_path, "/README") dataset_changes <- paste0(bids_path, "/CHANGES") # read files bids_readme <- read_lines(dataset_readme, skip_empty_rows = FALSE, lazy = FALSE) %>% paste(., collapse = " \n ") bids_changes <- read_lines(dataset_changes, skip_empty_rows = FALSE, lazy = FALSE) %>% paste(., collapse = " \n ") metadata_dataset <- fromJSON(file = dataset_description) sequence_map_df <- read_tsv(sequence_map, show_col_types = FALSE, lazy = FALSE) json_df <- read_tsv(json_metadata, show_col_types = FALSE, lazy = FALSE) %>% mutate(PatientSex = as.character(PatientSex)) json_merged_df <- json_df %>% left_join(sequence_map_df) %>% relocate(subject, group, session, sequence, BIDS_type, BIDS_sequence, relevant) %>% select(-total, -possible_sequence)
r json_merged_df %>% select(subject) %>% unique() %>% count() %>% kable()
r json_merged_df %>% select(session) %>% count() %>% kable()
r json_merged_df %>% select(relevant) %>% count() %>% kable()
r json_merged_df %>% filter(relevant == 1) %>% select(sequence) %>% count() %>% kable()
r json_merged_df %>% filter(relevant == 0) %>% select(sequence) %>% count() %>% kable()
r json_merged_df %>% select(ManufacturersModelName) %>% count() %>% kable()
r json_merged_df %>% select(Modality) %>% count() %>% kable()
r json_merged_df %>% select(MagneticFieldStrength) %>% count() %>% kable()
r json_merged_df %>% select(DeviceSerialNumber) %>% count() %>% kable()
r json_merged_df %>% select(SoftwareVersions) %>% count() %>% kable()
r json_merged_df %>% select(StationName) %>% count() %>% kable()
r json_merged_df %>% select(InstitutionalDepartmentName) %>% count() %>% kable()
r json_merged_df %>% select(InstitutionName) %>% count() %>% kable()
Authors: r metadata_dataset$Authors
Funding: r metadata_dataset$Funding
How to acknowledge: r metadata_dataset$HowToAcknowledge
License: r metadata_dataset$License
References and Links:
r metadata_dataset$ReferencesAndLinks %>% paste(., collapse = " \n ")
BIDS Version: r metadata_dataset$BIDSVersion
README
cat(bids_readme)
Changes
cat(bids_changes)
json_merged_df %>% df_select_n() %>% plot_bar()
json_merged_df %>% df_select_n() %>% filter(relevant == 1) %>% select(-relevant) %>% spread(. ,session, value = freq) %>% kableExtra::kable() %>% kableExtra::kable_styling("striped") %>% scroll_box(height = "400px")
json_merged_df %>% df_select_n() %>% filter(relevant == 0) %>% select(-relevant) %>% spread(. ,session, value = freq) %>% kableExtra::kable() %>% kableExtra::kable_styling("striped") %>% scroll_box(height = "400px")
p <-json_merged_df %>% df_select_n_group() %>% ggplot(aes(x = session, y = freq, fill = PatientSex)) + geom_bar(position="stack", stat = "identity") + theme_minimal() + facet_wrap(BIDS_type ~ BIDS_sequence + group, nrow = 2, labeller = label_both) + ggtitle("Barplots of n=Sequence , split by session-id and group-id") p
json_merged_df %>% df_select_n_group() %>% select(-relevant) %>% spread(session, freq) %>% kableExtra::kable() %>% kableExtra::kable_styling("striped") %>% scroll_box(height = "800px")
sessions <- json_merged_df$session %>% n_distinct() json_merged_df %>% calculate_comp_subjects(., sessions = sessions) %>% kableExtra::kable() %>% kableExtra::kable_styling("striped") %>% scroll_box(height = "800px")
json_merged_df %>% kableExtra::kable() %>% kableExtra::kable_styling("striped") %>% scroll_box(width = "1800px", height = "800px")
source("https://gist.githubusercontent.com/benmarwick/2a1bb0133ff568cbe28d/raw/fb53bd97121f7f9ce947837ef1a4c65a73bffb3f/geom_flat_violin.R") p_age <-json_merged_df %>% df_select_patient_info() %>% ggplot(aes(x = session, y = Age)) + geom_boxplot() + geom_flat_violin(position = position_nudge(x = .2, y = 0), trim = TRUE, alpha = .5, adjust = .8, scale = "width") + geom_point() + facet_wrap(. ~ group, labeller = label_both, nrow = 1) + ggtitle("Boxplots of Age, split by session-id and group-id") p_agesex <- json_merged_df %>% df_select_patient_info() %>% ggplot(aes(x = session, y = Age)) + geom_boxplot() + geom_flat_violin(position = position_nudge(x = .2, y = 0), trim = TRUE, alpha = .5, adjust = .8, scale = "width") + geom_point() + facet_wrap(. ~ group + PatientSex, labeller = label_both, nrow = 1) + theme(legend.position = "bottom") + ggtitle("Boxplots of Age and Sex, split by session-id and group-id") p_age / p_agesex
json_merged_df %>% df_select_patient_info() %>% group_by(session, group) %>% dplyr::summarize(mean = mean(Age), median = median(Age), sd = sd(Age), var = var(Age), iqr = IQR(Age), n = n()) %>% mutate(across(where(is.numeric), round, digits = 2)) %>% select(session, n, everything()) %>% kableExtra::kable() %>% kableExtra::kable_styling("striped") %>% scroll_box(height = "800px")
These tables could indicate implausibilities (like errors in ID), based on entrys, that contain sensitive information on the subject.
clean_string <- function(input, pattern) { input %>% str_remove_all(pattern) %>% str_remove_all("[:punct:]+") } json_merged_df %>% select(session, subject, PatientID, PatientName) %>% mutate( subject = str_remove(subject, "sub-"), PatientID = clean_string(PatientID, json_merged_df$subject), PatientName = clean_string(PatientName, json_merged_df$subject) ) %>% filter(PatientID != "" | PatientName != "") %>% unique() %>% datatable_setting()
json_merged_df %>% select(subject, PatientBirthDate) %>% unique() %>% select(subject) %>% count() %>% filter(freq > 1) %>% left_join(json_merged_df) %>% select(subject, session, AcquisitionDateTime, PatientBirthDate) %>% mutate(AcquisitionDateTime = as.Date(AcquisitionDateTime)) %>% unique() %>% group_by(subject) %>% mutate( Age = difftime(AcquisitionDateTime, PatientBirthDate) %>% time_length("years") %>% round(1), BirthDateDiff = difftime(PatientBirthDate, lag(PatientBirthDate)) %>% time_length("years") %>% round(1) ) %>% datatable_setting()
json_merged_df %>% select(subject, PatientSex) %>% unique() %>% select(subject) %>% count() %>% filter(freq > 1) %>% left_join(json_merged_df) %>% select(subject, session, PatientSex) %>% unique() %>% datatable_setting()
json_merged_df %>% select(subject, session, AcquisitionDateTime) %>% mutate(AcquisitionDateTime = as.Date(AcquisitionDateTime)) %>% unique() %>% group_by(subject) %>% select(session) %>% count() %>% filter(freq > 1) %>% datatable_setting()
json_merged_df %>% select(BIDS_type, relevant, sequence, SeriesDescription, ProtocolName) %>% group_by(across(everything())) %>% count() %>% select(BIDS_type, relevant, freq, everything()) %>% datatable_setting()
json_merged_df %>% select(subject, session, sequence) %>% group_by(across(everything())) %>% count() %>% filter(freq > 1) %>% left_join(json_merged_df) %>% select(subject, session, sequence, Path) %>% unique() %>% datatable_setting()
df_out <- json_merged_df %>% filter(BIDS_type == "anat") %>% filter(relevant == "1") if(nrow(df_out) != 0){ df_out %>% mutate(BIDS_sequence = as.factor(BIDS_sequence)) %>% kableExtra::kable() %>% kableExtra::kable_styling("striped") %>% scroll_box(height = "800px") } else { print("No anatomical files found.") }
df_out <-json_merged_df %>% filter(BIDS_type == "dwi") %>% filter(relevant == "1") if(nrow(df_out) != 0){ df_out %>% mutate(BIDS_sequence = as.factor(BIDS_sequence)) %>% kableExtra::kable() %>% kableExtra::kable_styling("striped") %>% scroll_box(height = "800px") } else { print("No diffusion-weighted files found.") }
df_out <-json_merged_df %>% filter(BIDS_type == "func") %>% filter(relevant == "1") if(nrow(df_out) != 0){ df_out %>% mutate(BIDS_sequence = as.factor(BIDS_sequence)) %>% kableExtra::kable() %>% kableExtra::kable_styling("striped") %>% scroll_box(height = "800px") } else { print("No functional files found.") }
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.