0

Suppose I am working with the mtcars dataset, and I would like to add:
1 to all values in the column: mpg
2 to all values in the column: cyl
3 to all values in the column: disp
I would like to keep all columns in mtcars, and refer to the columns by their names rather than their index.

Here's my current attempt:

library("tidyverse")
library("rlang")
data(mtcars)

mtcars_colnames <- quo(c("mpg", "cyl", "disp"))
num <- c(1, 2, 3)

mtcars %>% mutate(across(!!! mtcars_colnames, function(x) {x + num[col(.)]}))

I'm stuck on how to dynamically add (1,2,3) to columns (mpg, cyl, disp). Thanks in advance.

2 Answers 2

1

We could change the input by passing just a vector of strings instead of quosures and a named vector for 'num', then use the cur_column inside the across to match with the named vector of 'num', get the corresponding value and do the addition

library(dplyr)
mtcars_colnames <- c("mpg", "cyl", "disp")
num <- setNames(c(1, 2, 3), mtcars_colnames)
mtcars1 <- mtcars %>%
    mutate(across(all_of(mtcars_colnames), ~ num[cur_column()] + .))

-check the output

# // old data
mtcars %>% 
    select(all_of(mtcars_colnames)) %>% 
    slice_head(n = 5)
#                   mpg cyl disp
#Mazda RX4         21.0   6  160
#Mazda RX4 Wag     21.0   6  160
#Datsun 710        22.8   4  108
#Hornet 4 Drive    21.4   6  258
#Hornet Sportabout 18.7   8  360

# // new data
mtcars1 %>% 
    select(all_of(mtcars_colnames)) %>%
    slice_head(n = 5)
#                   mpg cyl disp
#Mazda RX4         22.0   8  163
#Mazda RX4 Wag     22.0   8  163
#Datsun 710        23.8   6  111
#Hornet 4 Drive    22.4   8  261
#Hornet Sportabout 19.7  10  363

Or if we prefer to pass a unnamed 'num' vector, then match the cur_column with the 'mtcars_colnamesinside theacross` to return the index and then use that to subset the 'num'

mtcars1 <- mtcars %>%
    mutate(across(all_of(mtcars_colnames), 
           ~ num[match(cur_column(), mtcars_colnames)] + .))
Sign up to request clarification or add additional context in comments.

Comments

1

Here are 3 base R approaches :

mtcars_colnames <- c("mpg", "cyl", "disp")
num <- c(1, 2, 3)
df <- mtcars

#option 1
df[mtcars_colnames] <- sweep(df[mtcars_colnames], 2, num, `+`)
#option 2
df[mtcars_colnames] <- Map(`+`, df[mtcars_colnames], num)
#option 3
df[mtcars_colnames] <- t(t(df[mtcars_colnames]) + num)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.