Distinguish between Cases Specified by Logical Conditions¶
Description¶
cases
allows to distinguish several cases defined logical
conditions. It can be used to code these cases into a vector. The
function can be considered as a multi-condition generalization of
ifelse
.
Usage¶
cases(...,check.xor)
Arguments¶
...
A sequence of logical expressions or assignment expressions containing logical expressions as “right hand side”.
check.xor
character (either
"warn"
,"stop"
, or"ignore"
) or logical; ifTRUE
or equal to"stop"
or"warn"
,cases
checks, whether the case conditions are mutually exclusive and exhaustive. If this is not satisfied andcheck.xor
equals"warn"
a warning is shown, otherwise an error exception is raised.
Value¶
If it is called with logical expressions as … arguments, cases
returns a factor, if it is called with assignment expressions the
function returns a vector with the same mode as the results of the
“assigned” expressions and with the same length as the logical
conditions.
Details¶
There are two distinct ways to use this function. Either the function
can be used to construct a factor that represents several logical cases
or it can be used to conditionally evaluate an expression in a manner
similar to ifelse
.
For the first use, the ...
arguments have to be a series of logical
expressions. cases
then returns a factor with as many levels as
logical expressions given as ...
arguments. The resulting factor
will attain its first level if the first condition is TRUE, otherwise
it will attain its second level if the second condition is TRUE, etc.
The levels will be named after the conditions or, if name tags are
attached to the logical expressions, after the tags of the expressions.
Not that the logical expressions all need to evaluate to logical
vectors of the same length, otherwise an error condition is raised.
For the second use, the ...
arguments have to be a series of
assignment expression of the type <expression> <- <logical
expression>
or <logical expression> -> <expression>
. For cases in
which the first logical expression is TRUE, the result of first
expression that appears on the other side of the assignment operator
become elements of the vector returned by cases
, for cases in which
the second logical expression is TRUE, the result of the second
expression that appears on the other side of the assignment operator
become elements of the vector returned by cases
, etc. Note that
the logical expressions also here all need to evaluate to logical
vectors of the same length. The expressions on the other side of the
assignment operator should also be either vectors of the same length
and mode or should scalars of the same mode, otherwise unpredictable
results may occur.
Examples¶
# Examples of the first kind of usage of the function
#
df <- data.frame(x = rnorm(n=20), y = rnorm(n=20))
df <- df[do.call(order,df),]
(df <- within(df,{
x1=cases(x>0,x<=0)
y1=cases(y>0,y<=0)
z1=cases(
"Condition 1"=x<0,
"Condition 2"=y<0,# only applies if x >= 0
"Condition 3"=TRUE
)
z2=cases(x<0,(x>=0 & y <0), (x>=0 & y >=0))
}))
Warning in cases(`Condition 1` = x < 0, `Condition 2` = y < 0, `Condition 3` =
TRUE) :
conditions are not mutually exclusive
x y z2 z1 y1 x1
11 -1.59794483 -0.2910983 x < 0 Condition 1 y <= 0 x <= 0
13 -0.95255849 -0.8014805 x < 0 Condition 1 y <= 0 x <= 0
19 -0.84979305 0.8329119 x < 0 Condition 1 y > 0 x <= 0
12 -0.70357671 -0.2829026 x < 0 Condition 1 y <= 0 x <= 0
7 -0.62072970 -1.5414336 x < 0 Condition 1 y <= 0 x <= 0
9 -0.30622146 1.1603755 x < 0 Condition 1 y > 0 x <= 0
3 -0.11564245 -0.8256470 x < 0 Condition 1 y <= 0 x <= 0
18 0.09134513 -0.3280777 (x >= 0 & y < 0) Condition 2 y <= 0 x > 0
5 0.13933241 -1.0400782 (x >= 0 & y < 0) Condition 2 y <= 0 x > 0
17 0.14521932 0.2027967 (x >= 0 & y >= 0) Condition 3 y > 0 x > 0
6 0.15077635 -0.3851748 (x >= 0 & y < 0) Condition 2 y <= 0 x > 0
10 0.15908675 -1.1518131 (x >= 0 & y < 0) Condition 2 y <= 0 x > 0
16 0.17144425 1.3391188 (x >= 0 & y >= 0) Condition 3 y > 0 x > 0
14 0.20747219 0.7251939 (x >= 0 & y >= 0) Condition 3 y > 0 x > 0
20 0.24934694 0.9909550 (x >= 0 & y >= 0) Condition 3 y > 0 x > 0
2 0.43202796 0.4728053 (x >= 0 & y >= 0) Condition 3 y > 0 x > 0
15 0.72909842 0.2382854 (x >= 0 & y >= 0) Condition 3 y > 0 x > 0
4 1.01008588 -0.3524120 (x >= 0 & y < 0) Condition 2 y <= 0 x > 0
1 1.12719970 0.6572697 (x >= 0 & y >= 0) Condition 3 y > 0 x > 0
8 2.04671242 0.2717768 (x >= 0 & y >= 0) Condition 3 y > 0 x > 0
xtabs(~x1+y1,data=df)
y1
x1 y > 0 y <= 0
x > 0 8 5
x <= 0 2 5
dd <- with(df,
try(cases(x<0,
x>=0,
x>1,
check.xor=TRUE)# let's be fussy
)
)
Error in cases(x < 0, x >= 0, x > 1, check.xor = TRUE) :
conditions are not mutually exclusive
dd <- with(df,
cases(x<0,x>=0,x>1)
)
Warning in cases(x < 0, x >= 0, x > 1) :
conditions are not mutually exclusive
genTable(range(x)~dd,data=df)
dd
x < 0 x >= 0
Min -1.59794483 0.09134513
Max -0.11564245 2.04671242
# An example of the second kind of usage of the function:
# A construction of a non-smooth function
#
fun <- function(x)
cases(
x==0 -> 1,
abs(x)> 1 -> abs(x),
abs(x)<=1 -> x^2
)
x <- seq(from=-2,to=2,length=101)
plot(fun(x)~x)
Warning in cases(1 <- x == 0, abs(x) <- abs(x) > 1, x^2 <- abs(x) <= 1) :
conditions are not mutually exclusive