在 R 中,对于多个列前缀,使用 dplyr::across 并计算 2 列之间的差异

Can*_*ice 3 r dplyr

zed <- data.frame(
  aAgg = c(5, 10, 15, 20),
  bAgg = c(8, 16, 24, 32),
  aPg = c(6, 9, 11, 24),
  bPg = c(7, 15, 22, 26)
)

diff_func <- function(col) {
  return(`{col}Agg` - `{colPg}`)
}

zed %>% 
  dplyr::mutate(dplyr::across(.cols = c('a', 'b'), .fns = diff_func, .names = "{col}Diff"))

# we want the output that this outputs, without having to have a mutate for each field.
zed <- zed %>%
  dplyr::mutate(aDiff = aAgg - aPg) %>%
  dplyr::mutate(bDiff = bAgg - bPg)
Run Code Online (Sandbox Code Playgroud)

我们正在尝试使用 dplyr 的across函数来创建多个列。对于每个列前缀(ab本例中),我们希望计算prefixAgg-之间的差异prefixPg,并命名新列prefixDiff。上例中的最后 3 行代码生成所需的输出。我们的diff_func目前不正确,抛出错误。

我们是否可以传递一个函数来across生成此输出?

akr*_*run 5

get我们可能需要在替换列名 ( ) 中的子字符串后循环遍历 'Agg' 列或 'Pg' 列以及相应的列cur_column(),并修改.names

\n
library(dplyr)\nlibrary(stringr)\nzed %>%\n   mutate(across(ends_with("Agg"), ~ .x -\n   get(str_replace(cur_column(), "Agg", "Pg")), \n   .names = "{str_replace(.col, 'Agg', 'Diff')}"))\n
Run Code Online (Sandbox Code Playgroud)\n

-输出

\n
  aAgg bAgg aPg bPg aDiff bDiff\n1    5    8   6   7    -1     1\n2   10   16   9  15     1     1\n3   15   24  11  22     4     2\n4   20   32  24  26    -4     6\n
Run Code Online (Sandbox Code Playgroud)\n
\n

或者使用两个across,得到差异 - 结果列将是 data.frame/tibble,然后unpackdata.frame 列

\n
library(tidyr)\nzed %>% \n  mutate(Diff = across(ends_with("Agg")) - across(ends_with("Pg"))) %>% \n  unpack(where(is.data.frame), names_sep = "")\n# A tibble: 4 \xc3\x97 6\n   aAgg  bAgg   aPg   bPg DiffaAgg DiffbAgg\n  <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>\n1     5     8     6     7       -1        1\n2    10    16     9    15        1        1\n3    15    24    11    22        4        2\n4    20    32    24    26       -4        6\n
Run Code Online (Sandbox Code Playgroud)\n

注意:如果需要,可以重命名列

\n
zed %>% \n  mutate(across(ends_with("Agg"), \n  .names = "{str_remove(.col, 'Agg')}Diff") - \n      across(ends_with("Pg")))\n  aAgg bAgg aPg bPg aDiff bDiff\n1    5    8   6   7    -1     1\n2   10   16   9  15     1     1\n3   15   24  11  22     4     2\n4   20   32  24  26    -4     6\n
Run Code Online (Sandbox Code Playgroud)\n
\n

或者也可以dplyoveracross2

\n
library(dplyover)\nzed %>%\n  mutate(across2(ends_with("Agg"), ends_with("Pg"), `-`, \n  .names_fn = ~ str_replace(.x, "Agg_.*", "Diff")))\n  aAgg bAgg aPg bPg aDiff bDiff\n1    5    8   6   7    -1     1\n2   10   16   9  15     1     1\n3   15   24  11  22     4     2\n4   20   32  24  26    -4     6\n
Run Code Online (Sandbox Code Playgroud)\n