R - 如何创建重复的自定义Ifelse函数 [英] R - How to Create Custom Ifelse function that repeats
问题描述
我非常熟悉R的标准ifelse语句,以及如何创建嵌套的ifelse语句。但是我想创建一个更好的版本,这样我就不必复制/粘贴ifelse这么多次了。
I am quite familiar with R's standard ifelse statement, and how to create nested ifelse statements. I however want to create a "better" version, so that I dont have to copy / paste ifelse so many times.
以此嵌套ifelse语句为例:
Take this nested ifelse statement for example:
df <- data.frame(b = 1:5)
df$a <- ifelse(df$b == 1,1,
ifelse(df$b == 2,2,
ifelse(df$b == 3,3,4)))
,我想做的是创建一个像我可以这样调用的函数:
Instead, what I would like to do is create a function like I could call like this:
df$a <- myFunction(df$b == 1,1,
df$b == 2,2,
df$b == 3,3,4)
我希望函数能够获取我输入的参数数量,从而知道要包含多少ifelse语句,然后将参数插入到正确的位置,无论我想要多少。
I would want the function to be able to pick up how many arguments I have entered, and thus know how many ifelse statements to include and then plug the arguments into the correct position, up to however many I want.
还有一些重复,但是当创建更长的嵌套ifelse语句时,不必重复那段代码,然后尝试跟踪结束括号的。
There is still some repetition, but when creating longer nested ifelse statements it would be nice to not have to repeat that piece of code, and then try to keep track of ending paren's.
推荐答案
我们可以使用 Reduce()
来构建所需的解析嵌套 ifelse()
调用树然后 eval()
it:
We can use Reduce()
to build up the required parse tree of nested ifelse()
calls and then eval()
it:
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函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!