Element wise multiplication of two lists

Viewed 46

I have a large data frame and I would like to sequentially multiply two lists of variables to create relevant interactions.

Does someone know how I iterate multiplications across multiple variables sequentially? Ideally using data.table or purrr

My data looks something like this

data(iris)
# I have two lists of variables
sepalvar <- c("Sepal.Length","Sepal.Width")
petalvar <- c("Petal.Length","Petal.Width")

#The final dataset should contain Sepal.Length*Petal.Length and a Sepal.Width*Petal.Width interactions. It would look something like this
setDT(iris)[,multlength:=Sepal.Length*Petal.Length
            ][,multwidth:=Sepal.Width*Petal.Width]
head(iris)
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species multlength multwidth
1:          5.1         3.5          1.4         0.2  setosa       7.14      0.70
2:          4.9         3.0          1.4         0.2  setosa       6.86      0.60
3:          4.7         3.2          1.3         0.2  setosa       6.11      0.64
4:          4.6         3.1          1.5         0.2  setosa       6.90      0.62
5:          5.0         3.6          1.4         0.2  setosa       7.00      0.72
6:          5.4         3.9          1.7         0.4  setosa       9.18      1.56

Is there a way I can iterate this across the two list sequentially creating variables with recognizable names?

thanks a lot in advance for your help

Best

1 Answers

We can mgetto get the values of the objects in a list for both 'sepalvar' and 'petalvar', and use Map to do the * for corresponding elements, and assign (:=) it to two new columns

library(data.table)
setDT(iris)[, c('multlength', 'multwidth')
       := Map(`*`, mget(sepalvar), mget(petalvar))]

-output

head(iris)
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species multlength multwidth
#1:          5.1         3.5          1.4         0.2  setosa       7.14      0.70
#2:          4.9         3.0          1.4         0.2  setosa       6.86      0.60
#3:          4.7         3.2          1.3         0.2  setosa       6.11      0.64
#4:          4.6         3.1          1.5         0.2  setosa       6.90      0.62
#5:          5.0         3.6          1.4         0.2  setosa       7.00      0.72
#6:          5.4         3.9          1.7         0.4  setosa       9.18      1.56

Or another option is to use .SD

setDT(iris)[,   c('multlength', 'multwidth') := 
            .SD[, ..sepalvar] * .SD[, ..petalvar]]
Related