Search code examples
rdplyrpurrr

Can I shorten and simplify my dplyr code with `across` or `{purrr}` syntax?


From the list corresp and df_modifies :

# Note : corresp must be a list and not a data.frame 

corresp <- list(
  a_remplacer = c("abricot1"),
  remplacant = c("abricot2")
)

df_modifies <- data.frame(
  produit = c("abricot1", "abricot2"),
  m0123 = c(3, NA),
  m0223 = c(2.5, NA),
  m0323 = c(3, 2),
  m0423 = c(NA, 3)
)

I'd like to get the following result :

   produit m0123 m0223 m0323 m0423
1 abricot2     3   2.5     2     3

My code is long and I'd like to shorten it maybe with across or {purrr}.

library(dplyr)

modifies <- data.frame(
  produit = corresp$remplacant) |> 
  mutate(
    m0123 = ifelse(is.na(df_modifies$m0123[df_modifies$produit %in% corresp$remplacant]),
                   df_modifies$m0123[which(!is.na(df_modifies$m0123))[1]],
                   df_modifies$m0123[df_modifies$produit %in% corresp$remplacant]),
    m0223 = ifelse(is.na(df_modifies$m0223[df_modifies$produit %in% corresp$remplacant]),
                   df_modifies$m0223[which(!is.na(df_modifies$m0223))[1]],
                   df_modifies$m0223[df_modifies$produit %in% corresp$remplacant]),
    m0323 = ifelse(is.na(df_modifies$m0323[df_modifies$produit %in% corresp$remplacant]),
                   df_modifies$m0323[which(!is.na(df_modifies$m0323))[1]],
                   df_modifies$m0323[df_modifies$produit %in% corresp$remplacant]),
    m0423 = ifelse(is.na(df_modifies$m0423[df_modifies$produit %in% corresp$remplacant]),
                   df_modifies$m0423[which(!is.na(df_modifies$m0423))[1]],
                   df_modifies$m0423[df_modifies$produit %in% corresp$remplacant])
  ) 

Can you help me ?


Solution

  • I'm not sure how a scaled version of this answer would work, but you can use across this way:

    df_modifies |> 
      summarise(across(-produit, \(x) ifelse(is.na(x[produit == corresp$remplacant]), 
                                             x[produit == corresp$a_remplacer],
                                             x[produit == corresp$remplacant])),
                produit = corresp$remplacant)
    
    #   m0123 m0223 m0323 m0423  produit
    # 1     3   2.5     2     3 abricot2