Home > Back-end >  multiplying one column in tibble by each element in vector to produce multiple new tibbles
multiplying one column in tibble by each element in vector to produce multiple new tibbles

Time:01-07

Given the tibble:

c1 <- c(1,2,3)
c2 <- c(4,5,6)
c3 <- c(7,8,9)
d1 <- as_tibble(data.frame(c1,c2,c3))

# A tibble: 3 × 3
     c1    c2    c3
  <dbl> <dbl> <dbl>
1     1     4     7
2     2     5     8
3     3     6     9

and the vector

v1 <- c(1,2,3)

I would like a tidyverse method to multiply c3 by each element in the vector to produce three new tibbles that look like this:

# A tibble: 3 × 3
     c1    c2    c3
  <dbl> <dbl> <dbl>
1     1     4     7
2     2     5     8
3     3     6     9

# A tibble: 3 × 3
     c1    c2    c3
  <dbl> <dbl> <dbl>
1     1     4     14
2     2     5     16
3     3     6     18

# A tibble: 3 × 3
     c1    c2    c3
  <dbl> <dbl> <dbl>
1     1     4     21
2     2     5     24
3     3     6     27

I got as far as this:

d1 %>%
    mutate(outer(c3, v1, FUN = "*"))

# A tibble: 3 × 4
     c1    c2    c3 `outer(c3, v1, FUN = "*")`[,1]  [,2]  [,3]
  <dbl> <dbl> <dbl>                          <dbl> <dbl> <dbl>
1     1     4     7                              7    14    21
2     2     5     8                              8    16    24
3     3     6     9                              9    18    27

but it is not really a tidy way and is still one object. What are some better methods?

CodePudding user response:

map (or the base R equivalent lapply) are usually good places to start when you want to output a list:

library(purrr)
library(dplyr)
map(v1, ~ d1 %>% mutate(c3 = .x * c3))

[[1]]
# A tibble: 3 × 3
     c1    c2    c3
  <dbl> <dbl> <dbl>
1     1     4     7
2     2     5     8
3     3     6     9

[[2]]
# A tibble: 3 × 3
     c1    c2    c3
  <dbl> <dbl> <dbl>
1     1     4    14
2     2     5    16
3     3     6    18

[[3]]
# A tibble: 3 × 3
     c1    c2    c3
  <dbl> <dbl> <dbl>
1     1     4    21
2     2     5    24
3     3     6    27

In base R:

lapply(v1, \(x) {d1[3] <- d1[3]*x; d1})

CodePudding user response:

Using transform in base R

 lapply(v1, \(x) transform(d1, c3 = c3 *x))

-output

[[1]]
  c1 c2 c3
1  1  4  7
2  2  5  8
3  3  6  9

[[2]]
  c1 c2 c3
1  1  4 14
2  2  5 16
3  3  6 18

[[3]]
  c1 c2 c3
1  1  4 21
2  2  5 24
3  3  6 27
  • Related