簡體   English   中英

在 R 中,使用 dplyr::across 並計算 2 列之間的差異,用於多列前綴

[英]In R, use dplyr::across and compute difference between 2 columns, for multiple column prefixes

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)

我們正在嘗試across function 中使用 dplyr 來創建多個列。 對於每個列前綴(在這種情況下ab ),我們想計算prefixAgg - prefixPg之間的差異,並將新列命名為prefixDiff 上面示例中的最后 3 行代碼生成所需的 output。 我們的diff_func當前不正確,拋出錯誤。

是否有一個我們可以傳遞的across將生成這個 output?

我們可能需要遍歷“Agg”列或“Pg”列,並在從列名( cur_column() )中替換 substring 並修改.namesget相應的列

library(dplyr)
library(stringr)
zed %>%
   mutate(across(ends_with("Agg"), ~ .x -
   get(str_replace(cur_column(), "Agg", "Pg")), 
   .names = "{str_replace(.col, 'Agg', 'Diff')}"))

-輸出

  aAgg bAgg aPg bPg aDiff bDiff
1    5    8   6   7    -1     1
2   10   16   9  15     1     1
3   15   24  11  22     4     2
4   20   32  24  26    -4     6

或者使用兩個 cross ,得到across - 結果列將是 data.frame/tibble,然后unpack data.frame 列

library(tidyr)
zed %>% 
  mutate(Diff = across(ends_with("Agg")) - across(ends_with("Pg"))) %>% 
  unpack(where(is.data.frame), names_sep = "")
# A tibble: 4 × 6
   aAgg  bAgg   aPg   bPg DiffaAgg DiffbAgg
  <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>
1     5     8     6     7       -1        1
2    10    16     9    15        1        1
3    15    24    11    22        4        2
4    20    32    24    26       -4        6

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

zed %>% 
  mutate(across(ends_with("Agg"), 
  .names = "{str_remove(.col, 'Agg')}Diff") - 
      across(ends_with("Pg")))
  aAgg bAgg aPg bPg aDiff bDiff
1    5    8   6   7    -1     1
2   10   16   9  15     1     1
3   15   24  11  22     4     2
4   20   32  24  26    -4     6

或者也可以將dplyoveracross2一起使用

library(dplyover)
zed %>%
  mutate(across2(ends_with("Agg"), ends_with("Pg"), `-`, 
  .names_fn = ~ str_replace(.x, "Agg_.*", "Diff")))
  aAgg bAgg aPg bPg aDiff bDiff
1    5    8   6   7    -1     1
2   10   16   9  15     1     1
3   15   24  11  22     4     2
4   20   32  24  26    -4     6

為什么不只是:

zed <- zed %>%
  mutate(aDiff = aAgg - aPg,
         bDiff = bAgg - bPg)

據我所知,你不能傳遞不同的前綴,但如果你願意,你可以重命名。 我不知道您為什么要為此使用cross,您能澄清一下嗎?

split.defaultdplyr解決方案(可能接近您可以獲得的最快解決方案;請參見此處):

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)
)

library(dplyr, warn.conflicts = F)
zed %>% 
  split.default(
    sub('^(.{1}).*', '\\1', names(zed))
  ) %>% 
  lapply(
    function(.x) .x[[1]] - .x[[2]]
  ) %>% 
  setNames(., paste0(names(.), 'Diff')) %>% 
  mutate(zed, !!!.)
#>   aAgg bAgg aPg bPg aDiff bDiff
#> 1    5    8   6   7    -1     1
#> 2   10   16   9  15     1     1
#> 3   15   24  11  22     4     2
#> 4   20   32  24  26    -4     6

reprex package (v2.0.1) 於 2022 年 8 月 9 日創建

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM