使用dplyr::summarise与dplyr::across和purrr::map对具有相同前缀的列求和

fafcakar  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(132)

我有一个 Dataframe ,我想对具有相同前缀的列值求和以生成一个新列。我目前的问题是它没有考虑到我的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")

"我所尝试的"

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

预期产出

drkbr07n

drkbr07n1#

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

library(dplyr)
library(dplyover) # https://timteafan.github.io/dplyover/

dat %>% 
  group_by(id) %>% 
  summarise(across2(ends_with("pre"),
                    ends_with("post"),
                    ~ sum(c(.x, .y)),
                    .names = "{pre}"
                    )
            )

#> # A tibble: 2 × 3
#>      id  var1  var2
#>   <int> <dbl> <dbl>
#> 1     1 -2.32 -5.55
#> 2     2  1.11 -9.54

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

h5qlskok

h5qlskok2#

当跨多列的操作变得复杂时,我们可以使用透视:

library(dplyr)
library(tidyr)

  dat %>% 
    pivot_longer(-c(id, index),
                 names_to = c(".value", "name"), 
                 names_sep = "\\.") %>% 
    group_by(id) %>% 
    summarise(var1 = sum(var1), var2=sum(var2))
id  var1  var2
  <int> <dbl> <dbl>
1     1 -2.32 -5.55
2     2  1.11 -9.54

相关问题