首页 > 解决方案 > 使用 mutate 编程以创建新的数据列

问题描述

有一个data.frame这样的:

df <- data.frame("Config" = c("C1","C1","C2","C2"), "SN1" = 1:4, "SN2" = 5:8)

我正在尝试df %<>% mutate更通用。这是一个例子:

df %<>%
  mutate(
    Tag=paste(
      Config,
      as.character(SN1),
      as.character(SN2),
      sep="_"
    )
  )

所需要的是将一个向量传递c("Config", "SN1", "SN2")给上面mutate或执行相同工作的替代方法,即将新列Tag插入到上面data.frame。谢谢您的帮助

标签: rdplyrrlang

解决方案


就像我在评论中提到的那样,这不是关于运算符的问题,%<>%而是关于在函数中使用非标准评估 (NSE) 的问题dplyr。有一个很好的小插曲,但是要掌握 NSE/tidy 评估的窍门仍然很棘手。

同样正如我所提到的,您作为示例所做的正是您所做的tidyr::unite,所以如果您只需要这些,您实际上不需要写任何东西。但这是一个很好的简单示例。

在这个函数custom_unite中,第一个参数是.data被操作的数据框(能够管道的习惯是第一个参数是数据框)。然后...捕获要粘贴在一起的灵活数量的裸列名称,new_col是要创建的列的裸列名称,并按sep原样传递给paste. (我无意中将参数的顺序从tidyr::unite,而col, ...不是..., new_col。)

您需要创建列的 quosures。对于单个裸列new_col,您可以使用,但是对于您使用的enquo列的灵活数量,您将使用它们进行拼接。quos...!!!

要创建新列,您将分配 with:=而不是=未引用的 quosure。

library(tidyverse)

custom_unite <- function(.data, ..., new_col, sep = "_") {
  cols <- quos(...)
  new_col_quo <- enquo(new_col)

  .data %>%
    mutate(!!new_col_quo := paste(!!!cols, sep = sep))
}

df %>%
  custom_unite(Config, SN1, SN2, new_col = Tag)
#>   Config SN1 SN2    Tag
#> 1     C1   1   5 C1_1_5
#> 2     C1   2   6 C1_2_6
#> 3     C2   3   7 C2_3_7
#> 4     C2   4   8 C2_4_8

reprex 包(v0.2.1)于 2018 年 12 月 14 日创建


推荐阅读