【问题标题】:How do I write a dplyr pipe-friendly function where a new column name is provided from a function argument?如何编写一个对 dplyr 管道友好的函数,其中从函数参数提供了一个新的列名?
【发布时间】:2021-08-26 18:12:16
【问题描述】:

我希望生成一个管道友好的函数,其中用户为该函数生成的新列指定“选择名称”作为函数参数之一。

在下面的函数中,我希望name_for_elective 是用户可以随意设置的东西,之后,用户可以期望他们的数据中会有一个新列,其名称是他们在此处提供的名称.

我查看了https://dplyr.tidyverse.org/reference/dplyr_data_masking.html,mutate() 函数文档,在此处搜索,并尝试使用https://dplyr.tidyverse.org/reference/rename.html,但无济于事。

 elective_open<-function(.data,name_for_elective,course,tiebreaker){ 
    name_for_elective<-rlang::ensym(name_for_elective)
    course<-rlang::ensym(course)
    tiebreaker<-rlang::ensym(tiebreaker)

     .data%>%
       mutate(!!name_for_elective =ifelse(!!tiebreaker==max(!!tiebreaker),1,0))%>%mutate(!!name_for_elective=ifelse(!!name_for_elective==0,!!course[!!name_for_elective==1],""))%>%
   filter(!(!!course %in% !!name_for_elective))

 }

我已包含此示例函数,因为有多个对所需新列名的引用,并且我不确定进行引用的上下文是否更改了语法。

如您所见,我希望!!name_for_elective 能让我为我们的新专栏命名,但没有。我玩过 {{}},没有使用 rlang::ensym,但仍然没有弄清楚。

任何解决方案将不胜感激。

这:Use dynamic variable names in `dplyr` 可能会有所帮助,但我似乎无法弄清楚如何扩展它以在多次引用 name 参数的情况下工作。

根据@MrFlick 的好建议,示例数据采用以下形式:

dat<-tibble(ID=c("AA","BB","AA","BB","AA","BB"),Class=c("A_Class","B_Class","C_Class","D_Class","E_Class","F_Class"),
        randomNo=c(.75,.43,.97,.41,.27,.38))

然后用户可以运行类似的东西:

dat2<-dat%>%
   elective_open(MyChosenName,Class,randomNo)

如果使用该函数一次,期望的结果是:

desired_result_1<-tibble(ID=c("AA","BB","AA","BB"),
                   Class=c("A_Class","D_Class","E_Class","F_Class"),
                   randomNo=c(.75,.41,.27,.38),
                   MyChosenName=c("C_Class","B_Class"))

目标是允许此函数在需要时再次使用,并指定不同的名称。

在用户运行的情况下:

dat3<-dat%>%
   elective_open(MyChosenName,Class,randomNo)%>%
   mutate(Just_Another_One=1)%>%
   elective_open(SecondName,Class,randomNo)

输出将是:

desired_result_2<-tibble(ID=c("AA","BB"),
                     Class=c("E_Class","F_Class"),
                     randomNo=c(.27,.38),
                     MyChosenName=c("C_Class","B_Class"),
                     Just_Another_One=c(1,1),
                     SecondName=c("A_Class","D_Class"))

实际上,可能有任意数量的具有相同 ID 的记录,以及任意数量的Class-es。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    在这种情况下,您可以坚持对变量使用“拥抱{{}}”选项。如果你想动态创建列名,你仍然需要使用:=。此处的不同之处在于,您可以将胶水样式语法与包含运算符一起使用来获取符号的名称。这适用于提供的数据。

    elective_open <- function(.data, name_for_elective, course, tiebreaker){ 
      .data%>%
        mutate("{{name_for_elective}}" := ifelse({{tiebreaker}}==max({{tiebreaker}}),1,0)) %>%
        mutate("{{name_for_elective}}" := ifelse({{name_for_elective}}==0,{{course}}[{{name_for_elective}}==1],"")) %>%
        filter(!({{course}} %in% {{name_for_elective}}))
    }
    

    【讨论】:

    • 成功了。在拥抱周围添加" 就可以了。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多