【问题标题】:nested if_else in dplyr mutate_ behaving unexpectedlydplyr mutate_ 中的嵌套 if_else 行为异常
【发布时间】:2018-05-10 15:20:37
【问题描述】:

我的目标是定义一个函数来将数值变量转换为 因子变量,具有定义的级别,并使用 dplyr 函数 mutate 在原始数据集中覆盖它。

按照之前的question 的答案,我设法覆盖了原始数据集中的变量,但现在 dplyr mutate_ 中的嵌套 if_else 行为异常,如下例所示:

    library(dplyr)
    library(lazyeval)


    set.seed(1234)
    a<-runif(10,1,13)
    b<-1:10
    data<-data.frame(cbind(a,b))
    data #original data
    #            a  b
    # 1   2.364441  1
    # 2   8.467593  2
    # 3   8.311297  3
    # 4   8.480553  4
    # 5  11.330985  5
    # 6   8.683727  6
    # 7   1.113949  7
    # 8   3.790606  8
    # 9   8.993005  9
    # 10  7.171014 10

    dataout1 <- mutate(data, a=factor(if_else(a<3,"low",if_else(a>3&a<6,"average","high"))))
    dataout1  # what I expect
    #          a  b
    # 1      low  1
    # 2     high  2
    # 3     high  3
    # 4     high  4
    # 5     high  5
    # 6     high  6
    # 7      low  7
    # 8  average  8
    # 9     high  9
    # 10    high 10

    #my function
    my_func<-function(datain,var,colname=eval(deparse(substitute(var)))){
      dataout <- datain %>% mutate_(.dots=setNames(list(interp(~factor(if_else(var<3,"low",
                                                                                  if_else(var>3&var<6
                                                                                         ,"average",
                                                                                          "high"))),
                                                              var=colname)), 
                                                colname)
                         )
    }

    dataout2<-my_func(data,a)
    dataout2 
      #       a  b
      # 1  high  1
      # 2  high  2
      # 3  high  3
      # 4  high  4
      # 5  high  5
      # 6  high  6
      # 7  high  7
      # 8  high  8
      # 9  high  9
      # 10 high 10

【问题讨论】:

    标签: r if-statement dplyr


    【解决方案1】:

    dplyr 的较新 (>= 0.7) 版本中,mutate_ 等函数的 _SE 版本已被弃用,取而代之的是新的复杂 quosure 语法。

    因此,您的函数可以重写为:

    my_func <- function(data_in, var){
        col_name <- quo_name(enquo(var))
        data_out <- data_in %>% mutate(!!col_name := ifelse(!!var < 3,
                                                          'low',
                                                          ifelse(!!var > 6,
                                                                 'high', 
                                                                 'medium')
                                                         )
                                    )
        return(data_out)
        }
    

    您可以阅读更多关于 quosures 和其他复杂性的信息 here。这个earlier StackOverflow question 也可能有帮助。

    【讨论】:

      猜你喜欢
      • 2021-10-22
      • 1970-01-01
      • 2019-01-13
      • 2021-06-16
      • 2010-10-12
      • 1970-01-01
      • 2019-07-31
      • 2013-05-26
      • 2015-04-06
      相关资源
      最近更新 更多