【问题标题】:How can I keep old columns and rename new columns when using `mutate` with `across`使用 `mutate` 和 `across` 时如何保留旧列并重命名新列
【发布时间】:2021-11-11 12:38:06
【问题描述】:

当我mutateacross数据时,.cols选择的列被突变的结果替换。我如何在以下情况下执行此操作:

  • 在输出中保留.cols 选择的列
  • 适当地自动重命名mutate创建的列?

例如:

require(dplyr)
#> Loading required package: dplyr
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
require(magrittr)
#> Loading required package: magrittr
set.seed(7337)

## Create arbitrary tibble
myTibble <- tibble(x = 1:10,
                   y = runif(10),
                   z = y * pi)

## I can mutate across these columns
mutate(myTibble, across(everything(), multiply_by, 2))
#> # A tibble: 10 x 3
#>        x       y      z
#>    <dbl>   <dbl>  <dbl>
#>  1     2 1.78    5.58  
#>  2     4 0.658   2.07  
#>  3     6 0.105   0.331 
#>  4     8 1.75    5.50  
#>  5    10 1.33    4.19  
#>  6    12 1.02    3.20  
#>  7    14 1.20    3.75  
#>  8    16 0.00794 0.0250
#>  9    18 0.108   0.340 
#> 10    20 1.74    5.45

## I can subsequently rename these columns
mutate(myTibble, across(everything(), multiply_by, 2)) %>% 
  rename_with(paste0, everything(), "_double")
#> # A tibble: 10 x 3
#>    x_double y_double z_double
#>       <dbl>    <dbl>    <dbl>
#>  1        2  1.78      5.58  
#>  2        4  0.658     2.07  
#>  3        6  0.105     0.331 
#>  4        8  1.75      5.50  
#>  5       10  1.33      4.19  
#>  6       12  1.02      3.20  
#>  7       14  1.20      3.75  
#>  8       16  0.00794   0.0250
#>  9       18  0.108     0.340 
#> 10       20  1.74      5.45

## But how can I achieve this (without the fuss of creating & joining an additional table):

# A tibble: 10 x 6
    # x      y     z           x_double y_double z_double
# <int>  <dbl> <dbl>        <dbl>    <dbl>    <dbl>
#   1     1 0.313  0.982      2    0.625    1.96 
  # 2     2 0.759  2.39       4    1.52     4.77 
  # 3     3 0.705  2.22       6    1.41     4.43 
  # 4     4 0.573  1.80       8    1.15     3.60 
  # 5     5 0.599  1.88      10    1.20     3.77 
  # 6     6 0.0548 0.172     12    0.110    0.344
  # 7     7 0.571  1.80      14    1.14     3.59 
  # 8     8 0.621  1.95      16    1.24     3.90 
  # 9     9 0.709  2.23      18    1.42     4.46 
  # 10    10 0.954  3.00     20    1.91     5.99 

reprex package (v2.0.1) 于 2021-09-16 创建

【问题讨论】:

  • dplyr::across docs中有这样的例子
  • @camille 不是真的 - 我正在寻找可以与 across 一起使用的东西,因为 mutate_at 已被取代。我已经自我回答了,因为我在这里找不到我想要的东西,但后来从文档中解决了。
  • 接受的答案就是这样做的。在要求问题替换 mutate_at 后更新
  • @camille 感谢您指出这一点。我不认为这是一个骗局 - 更新的答案是这个问题的答案,但问题有很大不同,我找不到那个答案,如果我看到它可能不会点击它跨度>

标签: r rename dplyr across


【解决方案1】:

使用across.names 参数

across 使用参数.names 命名其输出,这是传递给glue::glue() 的参数。这是一个字符串,其中"{.col}""{.fn}" 被替换为列名(由.cols 指定)和函数(由.fns 指定)

.names 的默认值为 NULL,相当于"{.col}"。这意味着每个变异的列都被分配了与.cols 中对应的相同名称,这有效地“覆盖”了输出中的这些列。

要生成所需的表格,您需要执行以下操作:

require(dplyr)
#> Loading required package: dplyr
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
require(magrittr)
#> Loading required package: magrittr
set.seed(7337)

## Create arbitrary tibble
myTibble <- tibble(x = 1:10,
                   y = runif(10),
                   z = y * pi)

mutate(myTibble, across(everything(), multiply_by, 2, .names = "{.col}_double"))
#> # A tibble: 10 x 6
#>        x       y      z x_double y_double z_double
#>    <int>   <dbl>  <dbl>    <dbl>    <dbl>    <dbl>
#>  1     1 0.889   2.79          2  1.78      5.58  
#>  2     2 0.329   1.03          4  0.658     2.07  
#>  3     3 0.0527  0.165         6  0.105     0.331 
#>  4     4 0.875   2.75          8  1.75      5.50  
#>  5     5 0.666   2.09         10  1.33      4.19  
#>  6     6 0.509   1.60         12  1.02      3.20  
#>  7     7 0.598   1.88         14  1.20      3.75  
#>  8     8 0.00397 0.0125       16  0.00794   0.0250
#>  9     9 0.0541  0.170        18  0.108     0.340 
#> 10    10 0.868   2.73         20  1.74      5.45

reprex package (v2.0.1) 于 2021-09-16 创建

这样,across.fns.names 一起使用可以做很多事情:

mutate(myTibble, across(everything(),
                        .fns = list(double = multiply_by, half = divide_by),
                        2,
                        .names = "{.col}_{.fn}"))
#> # A tibble: 10 x 9
#>        x       y      z x_double x_half y_double  y_half z_double  z_half
#>    <int>   <dbl>  <dbl>    <dbl>  <dbl>    <dbl>   <dbl>    <dbl>   <dbl>
#>  1     1 0.889   2.79          2    0.5  1.78    0.444     5.58   1.40   
#>  2     2 0.329   1.03          4    1    0.658   0.165     2.07   0.517  
#>  3     3 0.0527  0.165         6    1.5  0.105   0.0263    0.331  0.0827 
#>  4     4 0.875   2.75          8    2    1.75    0.437     5.50   1.37   
#>  5     5 0.666   2.09         10    2.5  1.33    0.333     4.19   1.05   
#>  6     6 0.509   1.60         12    3    1.02    0.255     3.20   0.800  
#>  7     7 0.598   1.88         14    3.5  1.20    0.299     3.75   0.939  
#>  8     8 0.00397 0.0125       16    4    0.00794 0.00199   0.0250 0.00624
#>  9     9 0.0541  0.170        18    4.5  0.108   0.0271    0.340  0.0850 
#> 10    10 0.868   2.73         20    5    1.74    0.434     5.45   1.36

【讨论】:

    猜你喜欢
    • 2021-08-30
    • 2021-03-01
    • 2022-08-23
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 2019-10-09
    相关资源
    最近更新 更多