Reputation: 93
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.
Upvotes: 2
Views: 280
Reputation: 886938
Using dplyr
library(dplyr)
iris %>%
mutate(across(all_of(petal_cols), ~ round(., digits = 0)))
Upvotes: 1
Reputation: 388807
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
Upvotes: 2