@@ -1019,41 +1019,48 @@ read_contrasts <-
10191019 success <- checkListIsSubset(blocking , colnames(samples ), " blocking variables" , " sample metadata" )
10201020 }
10211021
1022- # Extract design matrix columns from contrasts: the variable column plus any blocking factors.
1023- design_cols <- unique(na.omit(c(contrasts [[variable_column ]], blocking )))
1024- design_matrix <- samples [, design_cols , drop = FALSE ]
1025-
1026- # Ensure there are no NA values in the design matrix.
1027- if (any(is.na(design_matrix ))) {
1028- stop(" NA values found in one or more design matrix columns." )
1029- }
1030-
1031- # Check that the design matrix is full rank.
1032- mm <- model.matrix(~ . - 1 , data = design_matrix )
1033- if (qr(mm )$ rank < ncol(mm )) {
1034- stop(paste(" Design matrix is not full rank." , " Model matrix columns:" , paste(colnames(mm ), collapse = " , " ), " \n " ))
1035- }
1036-
1037- # Warn about continuous covariates in the design matrix columns.
1038- for (col in design_cols ) {
1039- if (is.numeric(samples [[col ]])) {
1040- warning(paste(" Column" , col , " is numeric and may be treated as continuous." ))
1022+ # Ensure reference and target are valid for their variable
1023+ for (i in 1 : nrow(contrasts )) {
1024+ blocking_vars <- simpleSplit(contrasts [[blocking_column ]][i ], " ;" )
1025+
1026+ # Extract design matrix columns from contrasts: the variable column plus any blocking factors.
1027+ # For formula-based contrasts, extract variables from the formula itself.
1028+ formula_vars <- character (0 )
1029+ if (" formula" %in% colnames(contrasts ) && ! is.na(contrasts $ formula [i ])) {
1030+ formula_vars <- all.vars(as.formula(contrasts $ formula [i ]))
10411031 }
1042- }
1043-
1044- # Check that values in design matrix columns do not contain disallowed special characters.
1045- for (col in design_cols ) {
1046- vals <- as.character(samples [[col ]])
1047- for (sc in c(" /" , " \\\\ " )) { # Default special characters: c("/", "\\\\")
1048- if (any(grepl(sc , vals ))) {
1049- warning(paste(" Column" , col , " contains special character" , sc ,
1050- " which may cause issues downstream." ))
1032+
1033+ design_cols <- unique(na.omit(c(contrasts [[variable_column ]][i ], blocking_vars , formula_vars )))
1034+ design_matrix <- samples [, design_cols , drop = FALSE ]
1035+
1036+ # Ensure there are no NA values in the design matrix.
1037+ if (any(is.na(design_matrix ))) {
1038+ stop(" NA values found in one or more design matrix columns." )
1039+ }
1040+
1041+ # Check that the design matrix is full rank.
1042+ mm <- model.matrix(~ . - 1 , data = design_matrix )
1043+ if (qr(mm )$ rank < ncol(mm )) {
1044+ stop(paste(" Design matrix is not full rank." , " Model matrix columns:" , paste(colnames(mm ), collapse = " , " ), " \n " ))
1045+ }
1046+
1047+ # Warn about continuous covariates in the design matrix columns.
1048+ for (col in design_cols ) {
1049+ if (is.numeric(samples [[col ]])) {
1050+ warning(paste(" Column" , col , " is numeric and may be treated as continuous." ))
1051+ }
1052+ }
1053+
1054+ # Check that values in design matrix columns do not contain disallowed special characters.
1055+ for (col in design_cols ) {
1056+ vals <- as.character(samples [[col ]])
1057+ for (sc in c(" /" , " \\\\ " )) { # Default special characters: c("/", "\\\\")
1058+ if (any(grepl(sc , vals ))) {
1059+ warning(paste(" Column" , col , " contains special character" , sc ,
1060+ " which may cause issues downstream." ))
1061+ }
10511062 }
10521063 }
1053- }
1054-
1055- # Ensure reference and target are valid for their variable
1056- for (i in 1 : nrow(contrasts )) {
10571064 var <- contrasts [i , variable_column ]
10581065 ref <- contrasts [i , reference_column ]
10591066 tgt <- contrasts [i , target_column ]
0 commit comments