将 dplyr::summarise 与 dplyr::across 和 purrr::map 一起使用以对具有相同前缀的列进行求和

Mar*_*rie 1 r dplyr purrr

我有一个数据框,我想在其中对具有相同前缀的列值求和以生成新列。我当前的问题是它没有考虑我的group_by变量并返回相同的值。问题的一部分是我在 across 函数中选择的 .cols 变量吗?

样本数据


library(dplyr)
library(purrr)

set.seed(10)

dat <- data.frame(id = rep(1:2, 5), 
                  var1.pre  = rnorm(10), 
                  var1.post = rnorm(10),
                  var2.pre  = rnorm(10), 
                  var2.post = rnorm(10) 
                   ) %>% 
  mutate(index = id) 

var_names = c("var1", "var2")

Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我尝试过的

sumfunction <- map(
  var_names,
  ~function(.){
    sum(dat[glue("{.x}.pre")], dat[glue("{.x}.post")], na.rm = TRUE)
  }
) %>% 
  setNames(var_names)

dat %>% 
 group_by(id) %>%
  summarise(
    across(
      .cols  = index,
      .fns   = sumfunction, 
      .names = "{.fn}"
    )
  ) %>% 
  ungroup
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

所需输出

在此输入图像描述

Tim*_*Fan 5

对于这个问题和类似的问题,我制作了“dplyover”包(它不在 CRAN 上)。在这里,我们可以使用dplyover::across2()循环遍历两个系列的列,首先是所有以 结尾的列"pre",其次是所有以 结尾的列"post"。为了获得正确的名称,我们可以使用 .names = "{pre}"来获取这两个系列的列的公共前缀。

\n
library(dplyr)\nlibrary(dplyover) # https://timteafan.github.io/dplyover/\n\ndat %>% \n  group_by(id) %>% \n  summarise(across2(ends_with("pre"),\n                    ends_with("post"),\n                    ~ sum(c(.x, .y)),\n                    .names = "{pre}"\n                    )\n            )\n\n#> # A tibble: 2 \xc3\x97 3\n#>      id  var1  var2\n#>   <int> <dbl> <dbl>\n#> 1     1 -2.32 -5.55\n#> 2     2  1.11 -9.54\n
Run Code Online (Sandbox Code Playgroud)\n

创建于 2022 年 12 月 14 日,使用reprex v2.0.2

\n