across() not working as intended after updating R to 4.1

Some parts of my script that worked as intended at R version 4.03 stopped working after updating R to 4.1.

Reprex

library(tidyverse)

tibble(x = c("a or b", "not reported"),
       y = c("c or d", "not reported")) %>%
  mutate(across(c(x, y), 
                ~str_to_title(.) %>%
                  str_replace_all(c(" Or " = " or ", 
                                    "Reported" = "reported")) %>% 
                  {ifelse(. == "Not reported", NA, .)}))

This should return:

# A tibble: 2 x 2
  x      y     
  <chr>  <chr> 
1 A or B C or D
2 NA     NA

But the actual output is:

# A tibble: 2 x 2
  x            y           
  <chr>        <chr>       
1 a or b       c or d      
2 not reported not reported

If I move the ifelse() part into a separate mutate() step,

tibble(x = c("a or b", "not reported"),
       y = c("c or d", "not reported")) %>%
  mutate(across(c(x, y), 
                ~str_to_title(.) %>%
                  str_replace_all(c(" Or " = " or ", 
                                    "Reported" = "reported")))) %>% 
  mutate(across(c(x, y), ~ifelse(. == "Not reported", NA, .)))

It works as intended.

# A tibble: 2 x 2
  x      y     
  <chr>  <chr> 
1 A or B C or D
2 NA     NA    

Is this a bug?

I havent installed v4.1 to look at this, but I would imagine there may be some pipe confusion as . placeholder is used with different intentions here

                ~str_to_title(.) 

at this point it is meant to substiture for values coming from across

 {ifelse(. == "Not reported", NA, .)}))

at this point you are wanting it to substitute from the results of the pipe that leads into it.

I think that the output you get is consistent with the explanations that you are getting the results from across from both uses of ., and I would think the second mutate you devised later make explicit that you want the post str_replace values rather than the prior ones.

1 Like

Yes, I agree with your idea that the unexpected result from the first case is related to pipe confusion due to the ambiguous meaning of . placeholder. Maybe I should be extra careful when using the placeholder in a pipe within the across context. Thank you for taking a look at this!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.