I have a code in which I want to be able to specify a certain condition, and then fill-in this condition at a later point in my code, executing it as regular code. A simple example shows it. The following code returns a certain value for d
depending on the values sampled for a
and b
.
a <- as.numeric(sample(1:2,1))
b <- as.numeric(sample(1:2,1))
d <- ifelse(a==1 & b==1,3,0)
But let's say I want to make it more flexible, and allow any condition to be specified, and then simply fill it in within the ifelse
. So for example we could have:
a <- as.numeric(sample(1:2,1))
b <- as.numeric(sample(1:2,1))
c <- as.numeric(sample(1:2,1))
And I would like to specify two conditions:
condition_1 <- "a==1"
condition_2 <- "b==1"
or
condition_1 <- "a==1"
condition_2 <- "c==1"
and so on. Then I would like to fill in this conditions into ifelse
. This does not work:
d <- ifelse(noquote(condition_1) & noquote(condition_1),3,0)
This also does not work:
d <- ifelse(paste(noquote(condition_1)) & paste(noquote(condition_1)),3,0)
I have tried anything I could think of but with no success. Is there a way to do this? More in general, how can I store parts of code, and then past them into the code at a later point and have it executed like the rest of the code? Please do not provide workarounds that only work for this specific example. I need to do something analogous in a much more complex code.
CodePudding user response:
"Storing parts of code [for later use]" sounds to me like using functions. You can pass functions as arguments to other functions. So you could do something like:
dFunc1 <- function(aVal, bVal) {
ifelse(a == aVal & b == bVal, 3, 0)
}
set.seed(1234)
a <- as.numeric(sample(1:2,1))
b <- as.numeric(sample(1:2,1))
d <- dFunc1(1, 1)
a
b
d
> a
[1] 2
> b
[1] 2
> d
[1] 0
and then
set.seed(1234)
dFunc2 <- function(aVal, cVal) {
ifelse(a == aVal & c == cVal, 3, 0)
}
c <- as.numeric(sample(1:2,1))
d <- dFunc2(1, 1)
c
d
> c
[1] 2
> d
[1] 0
If your derivations are embedded in another function, that's not a problem.
doItAll <- function(f, ...) {
set.seed(1234)
a <- as.numeric(sample(1:2,1))
b <- as.numeric(sample(1:2,1))
c <- as.numeric(sample(1:2,1))
d <- f(...)
return(list("a"=a, "b"=b, "c"=c, "d"=d))
}
doItAll(dFunc1, aVal=1, bVal=1)
$a
[1] 2
$b
[1] 2
$c
[1] 2
$d
[1] 0
and
doItAll(dFunc2, aVal=1, cVal=1)
$a
[1] 2
$b
[1] 2
$c
[1] 2
$d
[1] 0
The use of the elipsis (...
) is key to the ability of passing arbitrary arguments to functions that are called from inside another function.
CodePudding user response:
In the end I decided to solve this with a set of if
and else if
conditions. It seemed more practical than setting up a function as suggested by Limey.