【问题标题】:use dplyr mutate() in programming在编程中使用 dplyr mutate()
【发布时间】:2017-12-23 12:15:36
【问题描述】:

我正在尝试使用 mutate 将列名分配给变量。

df <-data.frame(x = sample(1:100, 50), y = rnorm(50))

new <- function(name){
     df%>%mutate(name = ifelse(x <50, "small", "big"))
}

当我跑步时

new(name = "newVar")

它不起作用。我知道mutate_() 可以提供帮助,但我很难将它与ifelse 一起使用。

任何帮助将不胜感激。

【问题讨论】:

  • 您在mutate 的末尾缺少),并且mutate 拼写错误。另外,在你的函数中调用像df 这样的全局变量时要小心。将df 作为参数传递给函数会更安全。
  • mutate_ 正在逐步淘汰。更新dplyr 并输入vignette('programming', 'dplyr')
  • 我的包都是最新的。

标签: r tidyverse nse dplyr


【解决方案1】:

基础 R 解决方案

df <-data.frame(x = sample(1:100, 50), y = rnorm(50))

new <- function(name){
    df[,name]='s'
    df[,name][df$x>50]='b'
    return(df)
}

我使用的是dplyr 0.5,所以我只是将base R 与mutate结合起来

new <- function(Name){

    df=mutate(df,ifelse(x <50, "small", "big"))
    names(df)[3]=Name
    return(df)
}

new("newVar")

【讨论】:

    【解决方案2】:

    使用dplyr 0.7.1 及其在 NSE 中的进步,您必须将UQ 参数传递给mutate,然后在分配时使用:=。这里有很多关于dplyr 和 NSE 编程的信息:https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html

    我已将函数参数的名称更改为 myvar 以避免混淆。如果您有更多类别需要重新编码,也可以使用 dplyr 中的 case_when 而不是 ifelse

    df <- data.frame(x = sample(1:100, 50), y = rnorm(50))
    
    new <- function(myvar){
        df %>% mutate(UQ(myvar) := ifelse(x < 50, "small", "big"))
    }
    
    new(myvar = "newVar")
    

    返回

         x        y newVar
    1   37  1.82669  small
    2   63 -0.04333    big
    3   46  0.20748  small
    4   93  0.94169    big
    5   83 -0.15678    big
    6   14 -1.43567  small
    7   61  0.35173    big
    8   26 -0.71826  small
    9   21  1.09237  small
    10  90  1.99185    big
    11  60 -1.01408    big
    12  70  0.87534    big
    13  55  0.85325    big
    14  38  1.70972  small
    15   6  0.74836  small
    16  23 -0.08528  small
    17  27  2.02613  small
    18  76 -0.45648    big
    19  97  1.20124    big
    20  99 -0.34930    big
    21  74  1.77341    big
    22  72 -0.32862    big
    23  64 -0.07994    big
    24  53 -0.40116    big
    25  16 -0.70226  small
    26   8  0.78965  small
    27  34  0.01871  small
    28  24  1.95154  small
    29  82 -0.70616    big
    30  77 -0.40387    big
    31  43 -0.88383  small
    32  88 -0.21862    big
    33  45  0.53409  small
    34  29 -2.29234  small
    35  54  1.00730    big
    36  22 -0.62636  small
    37 100  0.75193    big
    38  52 -0.41389    big
    39  36  0.19817  small
    40  89 -0.49224    big
    41  81 -1.51998    big
    42  18  0.57047  small
    43  78 -0.44445    big
    44  49 -0.08845  small
    45  20  0.14014  small
    46  32  0.48094  small
    47   1 -0.12224  small
    48  66  0.48769    big
    49  11 -0.49005  small
    50  87 -0.25517    big
    

    【讨论】:

    【解决方案3】:

    按照dlyr programming vignette,定义你的函数如下:

    new <- function(name)
    {
        nn <- enquo(name) %>% quo_name()
        df %>% mutate( !!nn := ifelse(x <50, "small", "big"))
    }
    

    enquo 接受其表达式参数并将其引用,然后quo_name 将其转换为字符串。由于现在引用了nn,我们需要告诉mutate 不要再次引用它。这就是!! 的用途。最后,:= 是一个辅助运算符,使其成为有效的 R 代码。请注意,使用此定义,您可以简单地将 newVar 而不是 "newVar" 传递给您的函数,保持 dplyr 样式。

    > new( newVar ) %>% head
        x           y newVar
     1 94 -1.07642088    big
     2 85  0.68746266    big
     3 80  0.02630903    big
     4 74  0.18323506    big
     5 86  0.85086915    big
     6 38  0.41882858  small
    

    【讨论】:

    • 接受了 meenaparam 的回答,但您的回答无疑也是一个很好的回答,这将有助于我正在编写的另一个函数。谢谢
    • 同意,我认为这也是一个非常有用的答案!
    • 终于,几个小时后,这篇文章解决了我的问题!
    猜你喜欢
    • 2018-11-17
    • 2015-03-20
    • 2015-03-20
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    相关资源
    最近更新 更多