What is the tidy equivalent of using `sweep` across rows?
Say I have a set of columns, named Intercept
, 1
, 2
, 3
in my example, and a set of coefficients, named c0
through c3
.
xs<-seq(.1,1,.1)
X <- cbind(Intercept=1, "1"=xs, "2"=xs^2, "3"=xs^3)
coefs <- c(c0=10, c1=2, c2=.5, c3=-1)
I want to multiply each column of X by the the corresponding coefficient.
sweep(
X, # x: the data array
2, # MARGIN: 2, to sweep across rows
coefs, # STATS: just the array of coefficients
`*`) # FUN: the function to use is multiplication
This gives what I want.
But if I had my data as a tibble (tidyX <- as_tibble(X)
), what is the tidy way of doing this?
tidyX %>% ... ?
It seems simple, and I imagine it involves dplyr::rowwise()
, perhaps, but I don't see the idiomatic way of doing this.
Solution 1:
Ah, just as soon as I finally post, I found an answer.
tidyX %>%
rowwise() %>%
mutate(across() * coefs)
I still find this syntax nonintuitive, but that does just what I'm looking for.
Solution 2:
If the column names are the same, we may loop across
the columns of 'tidyX' and use the column name (cur_column()
) to extract the corresponding column of 'coefs'. But, here the column name is different, so use match
to get the column index, extract ([[
) the column/element (if it is a named vector) from 'coefs' and multiply
library(dplyr)
tidyX %>%
mutate(across(everything(),
~ .x * coefs[[match(cur_column(), names(tidyX))]]))
Or an easier option is map2
(from purrr
) to loop over the corresponding columns of both datasets and multiply. If we want the output as a tibble/data.frame
, use _dfc
library(purrr)
map2_df(tidyX, coefs, `*`)
# A tibble: 10 × 4
Intercept `1` `2` `3`
<dbl> <dbl> <dbl> <dbl>
1 10 0.2 0.005 -0.001
2 10 0.4 0.02 -0.008
3 10 0.6 0.045 -0.027
4 10 0.8 0.08 -0.064
5 10 1 0.125 -0.125
6 10 1.2 0.18 -0.216
7 10 1.4 0.245 -0.343
8 10 1.6 0.32 -0.512
9 10 1.8 0.405 -0.729
10 10 2 0.5 -1