Home > other >  r - pass object into mutate
r - pass object into mutate

Time:05-22

I am having trouble with passing a previously defined object to mutate. I want to define item as a column name and pass it into mutate. However when I do so, mutate creates a new column, and does not replace values in the column defined in item

This code

item <- "HG13_2"

data <- data %>% 
  mutate(item = replace(item, sidtp %in% xfile$`PERSON LABEL`, 999))

produces this result, which I don't want

# A tibble: 11 × 4
   sidtp     HG13_2 HG14_2  item
   <chr>      <dbl>  <dbl> <dbl>
 1 person_1       1      1   999
 2 person_2       1      1   999
 3 person_3       1      1   999
 4 person_4       1      1   999
 5 person_5       1      1   999
 6 person_6       1      1   999
 7 person_7       1      1   999
 8 person_8       1      1   999
 9 person_9       1      1   999
10 person_10      1      1   999
11 person_11      1      1     1

If I hard code the column names into mutate like this

data <- data %>% 
  mutate(HG13_2 = replace(HG13_12, sidtp %in% xfile$`PERSON LABEL`, 999))

it produces the result I want:

# A tibble: 11 × 3
   sidtp     HG13_2 HG14_2
   <chr>      <dbl>  <dbl>
 1 person_1     999      1
 2 person_2     999      1
 3 person_3     999      1
 4 person_4     999      1
 5 person_5     999      1
 6 person_6     999      1
 7 person_7     999      1
 8 person_8     999      1
 9 person_9     999      1
10 person_10    999      1
11 person_11      1      1

How can I get mutate to accept item and replace the values in HG13_2 instead of creating a new column?

CodePudding user response:

Using the .data pronoun, the spelling special assignment operator := and some glue syntax on the LHS you could do:

library(dplyr)

data <- data.frame(
  sidtp = paste("person", 1:12, sep = "_"),
  HG13_2 = 1,
  HG14_2 = 1
)

item <- "HG13_2"

xfile <- data.frame("PERSON LABEL" = paste("person", 1:11, sep = "_"), check.names = FALSE)

data |> 
  mutate("{item}" := replace(.data[[item]], sidtp %in% xfile$`PERSON LABEL`, 999))
#>        sidtp HG13_2 HG14_2
#> 1   person_1    999      1
#> 2   person_2    999      1
#> 3   person_3    999      1
#> 4   person_4    999      1
#> 5   person_5    999      1
#> 6   person_6    999      1
#> 7   person_7    999      1
#> 8   person_8    999      1
#> 9   person_9    999      1
#> 10 person_10    999      1
#> 11 person_11    999      1
#> 12 person_12      1      1

CodePudding user response:

Data from @stefan, We could also use := and evaluating with !! and using sym to back conversion:

item <- "HG13_2"

xfile <- data.frame("PERSON LABEL" = paste("person", 1:11, sep = "_"), check.names = FALSE)

data <- data.frame(
  sidtp = paste("person", 1:12, sep = "_"),
  HG13_2 = 1,
  HG14_2 = 1
)

data %>% 
  mutate(!! item := replace(!! rlang:: sym(item), sidtp %in% xfile$`PERSON LABEL`, 999))
       sidtp HG13_2 HG14_2
1   person_1    999      1
2   person_2    999      1
3   person_3    999      1
4   person_4    999      1
5   person_5    999      1
6   person_6    999      1
7   person_7    999      1
8   person_8    999      1
9   person_9    999      1
10 person_10    999      1
11 person_11    999      1
12 person_12      1      1
  • Related