2

I am interested in the data.table equivalent of using across() to transform multiple columns and then return the whole dataset. I am able to use lapply() on a subset of columns, but this only returns the selected columns as demonstrated below.

Just wondering if a simple solution to this problem can be found. I have also attached the intended solution using the dplyr method. Thanks!

# Convert iris into data.table object
iris <- setDT(datasets::iris)

# Select columns containing "Petal"
petal_cols <- str_subset(colnames(iris), "Petal")

# Transform multiple columns  
iris[,
     lapply(.SD, round, digits = 0),
     .SDcols = petal_cols]

# This does not work  
# iris[,
#      c("col1", "col2") := unlist(lapply(.SD, round, digits = 0), recursive = F),
#      .SDcols = petal_cols]

# dplyr solution ---------------------------------------------------------------
iris %>%
  mutate(across(contains("Petal"), ~round(.x, digits = 0)))

Note: I have read another post but the solution using c(cols) := unlist(lapply(...), recursive = FALSE) didn't work for me.

EMD
  • 93
  • 7

2 Answers2

2

Assign the output from lapply back to petal_cols.

library(data.table)
iris[, (petal_cols) := lapply(.SD, round, digits = 0),.SDcols = petal_cols]
iris

#     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
#  1:          5.1         3.5            1           0    setosa
#  2:          4.9         3.0            1           0    setosa
#  3:          4.7         3.2            1           0    setosa
#  4:          4.6         3.1            2           0    setosa
#  5:          5.0         3.6            1           0    setosa
# ---                                                            
#146:          6.7         3.0            5           2 virginica
#147:          6.3         2.5            5           2 virginica
#148:          6.5         3.0            5           2 virginica
#149:          6.2         3.4            5           2 virginica
#150:          5.9         3.0            5           2 virginica
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
1

Using dplyr

library(dplyr)
iris %>%
    mutate(across(all_of(petal_cols), ~ round(., digits = 0)))
akrun
  • 874,273
  • 37
  • 540
  • 662