llewmills
llewmills

Reputation: 3568

Combining two column transformations in a single mutate() function in dplyr 1.0.0

I need to first transform a subset of character columns into numeric columns using mutate and then round those numeric columns to two decimal places.

Here's some toy data.

library(dplyr)

# dataset made up of all character columns
d <- data.frame(point = c("point = 1", "point = 2", "point = 3"),
                b = as.character(c(1.0004, 3.4567, 4.6789)),
                c = as.character(c(10.231, 11.345, 18.987)),
                stringsAsFactors = F)
str(d)

# 'data.frame': 3 obs. of  3 variables:
# $ point: chr  "point = 1" "point = 2" "point = 3"
# $ b    : chr  "1.0004" "3.4567" "4.6789"
# $ c    : chr  "10.231" "11.345" "18.987"

Now we can use mutate to transform the last two columns to numeric

d %>%
  mutate(across(!contains("point"), as.numeric)) -> d2

str(d2)

# 'data.frame': 3 obs. of  3 variables:
# $ point: chr  "point = 1" "point = 2" "point = 3"
# $ b    : num  1 3.46 4.68
# $ c    : num  10.2 11.3 19

Now to round the recently-transformed numeric columns to two decimal places

d2 %>% mutate(across(where(is.numeric), round, 2))

#       point    b     c
# 1 point = 1 1.00 10.23
# 2 point = 2 3.46 11.35
# 3 point = 3 4.68 18.99

What I want to know is can the two transformations be performed inside a single mutate() call?

Upvotes: 1

Views: 173

Answers (2)

HubertL
HubertL

Reputation: 19544

You can also use purrr::compose() to nest functions calls

d %>%
  mutate( across( !contains( "point" ), 
                  purrr::compose( round, as.numeric )))

Upvotes: 1

d %>%
  mutate(across(!contains("point"), ~round(as.numeric(.x), 2)))

Upvotes: 2

Related Questions