@@ -38,7 +38,7 @@ parse_condition_formulas <- function(formulas, mask, fn) {
3838 # Process each formula: condition ~ value
3939 for (i in seq_len(n )) {
4040 f <- formulas [[i ]]
41- if (! inherits (f , " formula " )) {
41+ if (! is_formula (f , lhs = TRUE )) {
4242 validation_error(paste0(" Each argument to " , fn , " () must be a two-sided formula" ))
4343 }
4444 # f[[2]] is LHS (logical condition), f[[3]] is RHS (value when TRUE)
@@ -95,7 +95,17 @@ parse_from_to_mapping <- function(x, from, to) {
9595 query [[i ]] <- call_binding(" is.na" , x )
9696 } else if (length(from_i ) > 1 ) {
9797 # Multiple values: use %in% to match any
98- query [[i ]] <- call_binding(" %in%" , x , from_i )
98+ # If NA is in the vector, also match NA using is.na()
99+ if (any(is.na(from_i ))) {
100+ non_na_values <- from_i [! is.na(from_i )]
101+ if (length(non_na_values ) > 0 ) {
102+ query [[i ]] <- call_binding(" %in%" , x , non_na_values ) | call_binding(" is.na" , x )
103+ } else {
104+ query [[i ]] <- call_binding(" is.na" , x )
105+ }
106+ } else {
107+ query [[i ]] <- call_binding(" %in%" , x , from_i )
108+ }
99109 } else {
100110 query [[i ]] <- x == from_i
101111 }
@@ -123,7 +133,7 @@ parse_formula_mapping <- function(x, formulas, mask, fn) {
123133 value <- vector(" list" , n )
124134 for (i in seq_len(n )) {
125135 f <- formulas [[i ]]
126- if (! inherits (f , " formula " )) {
136+ if (! is_formula (f , lhs = TRUE )) {
127137 validation_error(paste0(" Each argument to " , fn , " () must be a two-sided formula" ))
128138 }
129139 # f[[2]] is LHS (value to match), f[[3]] is RHS (replacement)
@@ -138,7 +148,17 @@ parse_formula_mapping <- function(x, formulas, mask, fn) {
138148 query [[i ]] <- call_binding(" is.na" , x )
139149 } else if (! inherits(lhs , " Expression" ) && length(lhs ) > 1 ) {
140150 # Vector LHS: c("a", "b") ~ "X" matches any value in the vector
141- query [[i ]] <- call_binding(" %in%" , x , lhs )
151+ # If NA is in the vector, also match NA using is.na()
152+ if (any(is.na(lhs ))) {
153+ non_na_values <- lhs [! is.na(lhs )]
154+ if (length(non_na_values ) > 0 ) {
155+ query [[i ]] <- call_binding(" %in%" , x , non_na_values ) | call_binding(" is.na" , x )
156+ } else {
157+ query [[i ]] <- call_binding(" is.na" , x )
158+ }
159+ } else {
160+ query [[i ]] <- call_binding(" %in%" , x , lhs )
161+ }
142162 } else {
143163 query [[i ]] <- x == lhs
144164 }
0 commit comments