I have a data.table with which I'd like to perform the same operation on certain columns. The names of these columns are given in a character vector. In this particular example, I'd like to multiply all of these columns by -1.
Some toy data and a vector specifying relevant columns:
library(data.table) dt <- data.table(a = 1:3, b = 1:3, d = 1:3) cols <- c("a", "b")
Right now I'm doing it this way, looping over the character vector:
for (col in 1:length(cols)) { dt[ , eval(parse(text = paste0(cols[col], ":=-1*", cols[col])))] }
Is there a way to do this directly without the for loop?
You can use the apply() function to apply a function to each row in a matrix or data frame in R. where: X: Name of the matrix or data frame. MARGIN: Dimension to perform operation across.
table() function in R Language is used to create a categorical representation of data with variable name and the frequency in the form of a table. Syntax: table(x) Parameters: x: Object to be converted.
table in R Programming Language. For applying a function to each row of the given data. table, the user needs to call the apply() function which is the base function of R programming language, and pass the required parameter to this function to be applied in each row of the given data. table in R language.
This seems to work:
dt[ , (cols) := lapply(.SD, "*", -1), .SDcols = cols]
The result is
a b d 1: -1 -1 1 2: -2 -2 2 3: -3 -3 3
There are a few tricks here:
(cols) :=
, the result is assigned to the columns specified in cols
, instead of to some new variable named "cols"..SDcols
tells the call that we're only looking at those columns, and allows us to use .SD
, the S
ubset of the D
ata associated with those columns.lapply(.SD, ...)
operates on .SD
, which is a list of columns (like all data.frames and data.tables). lapply
returns a list, so in the end j
looks like cols := list(...)
.EDIT: Here's another way that is probably faster, as @Arun mentioned:
for (j in cols) set(dt, j = j, value = -dt[[j]])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With