0

I'd like to apply an if_else function to several columns of my dataframe, with a dynamic name of variable to assign, the function is as follows:

retraitement <- function(Col, Taille) if_else(TAILLE== Taille,get(paste0("score_", str_replace(Col, "Score", ""), "_", Taille)),Col)

I've created the columns before and filled them with NA values :

columnsToAdd <- c(
  "Score1", "Score13", "Score49")
df[,columnsToAdd]=NA

What I want is to apply this function to the columns specified above like :

df<- df%>%
  mutate_at(all_of(columnsToAdd), retraitement, Taille = "PE") %>%
  mutate_at(all_of(columnsToAdd), retraitement, Taille = "MGE")

The problem is that I have this error message :

Caused by error in get(): ! first argument has length > 1

How can I fix it ?

Example

If we take as an example "Score1" variable, the original df is:

Score1 1_PE 1_MGE TAILLE
NA 12 28 MGE
NA 14 32 PE

After applying the function, it will be in my mind:

Score1 1_PE 1_MGE TAILLE
28 12 28 MGE
14 14 32 PE

As displayed above, the values assignment would be :

If Taille == "GE" then Score1 = 1_GE
If Taille == "MGE" then Score1 = 1_MGE 
So globally : If taille =="X" then Score1 = 1_X

It is important to keep in mind that I have several columns like "Score1" so applying a custom function would be better.

Thanks in advance

WalliYo_
  • 173
  • 7
  • It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Mar 23 '23 at 15:11

2 Answers2

0

Note that R doesn't allow variable names to start with a numeric, I changed the variable names accordingly:

df <- tibble::tribble(~PE_1, ~MGE_1, ~TAILLE,
                      12, 28, "MGE",
                      14, 32, "PE")

library(dplyr)
library(tidyr)

df |> 
  mutate(id = row_number()) |> 
  pivot_longer(-c(id, TAILLE)) |> 
  mutate(Score1 = if_else(stringr::str_detect(name, TAILLE), value, NA_integer_)) |>
  group_by(id) |> 
  fill(Score1, .direction = "updown") |> 
  ungroup() |> 
  pivot_wider() |> 
  select(Score1, PE_1, MGE_1, TAILLE)

# A tibble: 2 × 4
  Score1  PE_1 MGE_1 TAILLE
   <dbl> <dbl> <dbl> <chr> 
1     28    12    28 MGE   
2     14    14    32 PE   
Phil
  • 7,287
  • 3
  • 36
  • 66
  • Thanks for you anwer. The main fact here is to apply a function to several columns that have the same names format as Score1. Is there a way to apply the "retraitement" function i've done in my original post to several variables ? – WalliYo_ Mar 23 '23 at 15:31
  • I don't know because I never use `get()` as I find this kind of method clunky. The code I provided can definitely be adapted to be applied to multiple columns, if you provide the output of `dput(head(df))` as part of your question, it would give me a clear idea on how to do so. – Phil Mar 23 '23 at 15:38
0

Maybe you are looking to subset the data with row selected by TAILLE==taille and column with TAILLE name ?

it looks like df[df$TAILLE==taille,paste0("X1_",taille)] for me.

# with MGE
score_taille = function(df, taille = "MGE"){
  df = df %>%
    mutate(score = ifelse(TAILLE==taille, df[df$TAILLE==taille,paste0("X1_",taille)] , NA))
  return(df)
}
score_taille(df)

  X1_PE X1_MGE TAILLE score
1    12     28    MGE    28
2    14     32     PE    NA
Wael
  • 1,640
  • 1
  • 9
  • 20