使用 purrr::map2 (?) 将新列添加到数据框

des*_*hen 2 r purrr tidyverse

我再次陷入了这个看似简单的任务。

我有以下数据框:

df <- data.frame(x1 = 1:3,
                 x2 = 2:4,
                 x3 = 3:5,
                 y1 = 1:3,
                 y2 = 2:4,
                 y3 = 3:5)
Run Code Online (Sandbox Code Playgroud)

我现在只想“循环”每个下标并将 x* 与 y* 列相乘,即 x1 * y1、x2 * y2 等,并将这些结果添加到我的数据中。

对于这些类型的任务,我总是认为这应该可以通过某种map方法轻松完成,但我没有让它发挥作用,例如

library(tidyverse)
df |>
  map2(.x = _,
       .y = 1:3,
       .f = ~.x |>
         mutate(!!sym(paste0(results, .y)) := !!sym(paste0(x, .y)) * !!sym(paste0(y, .y))))
Run Code Online (Sandbox Code Playgroud)

不起作用。

我还考虑过使用 的东西across,但这也行不通,因为我无法告诉对 x 和 y 输入进行“矢量化”。

有任何想法吗?

ste*_*fan 5

使用reduce而不是map2你可以这样做:

library(dplyr)
library(purrr)

df |>
  reduce(1:3,
    .f = ~ .x |>
      mutate(!!sym(paste0("results", .y)) := !!sym(paste0("x", .y)) * !!sym(paste0("y", .y))),
    .init = _
  )
#>   x1 x2 x3 y1 y2 y3 results1 results2 results3
#> 1  1  2  3  1  2  3        1        4        9
#> 2  2  3  4  2  3  4        4        9       16
#> 3  3  4  5  3  4  5        9       16       25
Run Code Online (Sandbox Code Playgroud)


Maë*_*aël 5

诀窍是使用across两次:

library(dplyr)
df |>
  mutate(across(starts_with("x"), .names = "xy{gsub('x', '', col)}") * across(starts_with("y")))

#  x1 x2 x3 y1 y2 y3 xy1 xy2 xy3
#1  1  2  3  1  2  3   1   4   9
#2  2  3  4  2  3  4   4   9  16
#3  3  4  5  3  4  5   9  16  25
Run Code Online (Sandbox Code Playgroud)

  • 哈哈。这是一段奇怪的代码。永远不会想到像这样使用“across”(而且这确实有效)。(: (2认同)