R - 如何创建重复的自定义 Ifelse 函数

标签 r if-statement

我非常熟悉 R 的标准 ifelse 语句,以及如何创建嵌套的 ifelse 语句。但是,我想创建一个“更好”的版本,这样我就不必多次复制/粘贴 ifelse。

以这个嵌套的 ifelse 语句为例:

df <- data.frame(b = 1:5)

df$a <- ifelse(df$b == 1,1,
        ifelse(df$b == 2,2,
        ifelse(df$b == 3,3,4)))

相反,我想做的是创建一个函数,就像我可以这样调用:
df$a <- myFunction(df$b == 1,1,
                   df$b == 2,2,
                   df$b == 3,3,4)

我希望该函数能够获取我输入的参数数量,从而知道要包含多少 ifelse 语句,然后将参数插入正确的位置,直到我想要的数量为止。

仍然有一些重复,但是在创建更长的嵌套 ifelse 语句时,最好不必重复那段代码,然后尝试跟踪结束括号的。

最佳答案

我们可以使用 Reduce()构建所需的嵌套解析树 ifelse()打电话然后 eval()它:

ifelses <- function(...) {
    ## validate number of args is at least 3 and odd
    stopifnot(nargs()>=3L);
    stopifnot(nargs()%%2L==1L);
    ## precompute the required number of calls and the argument parse tree list
    num <- (nargs()-1L)%/%2L;
    cl <- match.call();
    ## build up the parse tree of nested ifelse() calls using Reduce(), then eval() it
    ## terminology (following docs): ifelse(test,yes,no)
    eval(Reduce(
        function(i,noArg) call('ifelse',cl[[i]],cl[[i+1L]],noArg),
        seq(2L,by=2L,len=num), ## indexes of "test" args
        cl[[length(cl)]], ## first (innermost) "no" arg
        T ## proceed from right-to-left, IOW inside-out wrt parse tree
    ));
}; ## end ifelses()

有用的文档:
  • nargs()
  • stopifnot()
  • match.call()
  • Reduce()
  • call()
  • eval()
  • seq()
  • ifelse()

  • 演示:
    ifelses(c(F,T,F,F),1:4,c(T,F,F,F),5:8,c(F,T,F,T),9:12,13:16);
    ## [1]  5  2 15 12
    

    OP的例子:
    df <- data.frame(b=1:5);
    df$a <- ifelses(df$b==1L,1L,df$b==2L,2L,df$b==3L,3L,4L);
    df;
    ##   b a
    ## 1 1 1
    ## 2 2 2
    ## 3 3 3
    ## 4 4 4
    ## 5 5 4
    

    关于R - 如何创建重复的自定义 Ifelse 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39174101/

    相关文章:

    r - 安装 R 包 Ubuntu 22.04.1 LTE 时的包 libcurl4-openssl-dev 问题

    计数出现的正则表达式匹配算法

    css - 使用 BoundField 在 GridView 上使用验证

    r - 按索引(日期)拆分 xts 对象

    r - 将多边形添加到 R Shiny 传单 map

    r - 是否可以在 Rmarkdown 中定义信头标题?

    php - 需要 PHP 帮助 : Trying to Pull MySQL Data From Record Matching Variable. 变量由 If-Then 语句设置。部分有效

    java - 为什么第二次运行后才出现 "Try a higher/lower number."?

    python - 在 Python 中是否有更简洁的方法来编写此 bool 比较?

    r - geom_text 在所有方面写入所有数据