if-else vs ifelse with lists
if ( cond) { yes } else { no }
is a control structure. It was designed to effect programming forks rather than to process a sequence. I think many people come from SPSS or SAS whose authors chose "IF" to implement conditional assignment within their DATA or TRANSFORM functions and so they expect R to behave the same. SA and SPSS both have implicit FOR-loops in there Data steps. Whereas R came from a programming tradition. R's implicit for-loops are built in to the many vectorized functions (including ifelse
). The lapply/sapply fucntions are the more Rsavvy way to implement most sequential processing, although they don't succeed at doing lagged variable access, especially if there are any randomizing features whose "effects" get cumulatively handled.
ifelse
takes an expression that builds a vector of logical values as its first argument. The second and third arguments need to be vectors of equal length and either the first of them or the second gets chosen. This is similar to the SPSS/SAS IF
commands which have an implicit by-row mode of operation.
Ifelse only returns first element of list
ifelse
is for vectors, use if
/else
for scalar comparisons.
if(length(list1)<length(list2)) list2 else list1
#$x
#[1] 1 2 3
#$y
#[1] 4 5 6
#$z
#[1] 7 8 9
ifelse
returns output of same length as the test that we are performing. length(length(list1)<length(list2))
is 1 hence the output from it is also of length 1.
else if(){} VS ifelse()
The if
construct only considers the first component when a vector is passed to it, (and gives a warning)
if(sample(100,10)>50)
print("first component greater 50")
else
print("first component less/equal 50")
The ifelse
function performs the check on each component and returns a vector
ifelse(sample(100,10)>50, "greater 50", "less/equal 50")
The ifelse
function is useful for transform
, for instance. It is often useful to
use &
or |
in ifelse
conditions and &&
or ||
in if
.
R - if-else applied to a list
You can use lapply
and transform
/within
. There are three possibilities:
a)
ifelse
lapply(myfiles, transform, V3 = ifelse(V2 > 50, V3, NA))
b) mathematical operators (potentially more efficient)
lapply(myfiles, transform, V3 = NA ^ (V2 <= 50) * V3)
c)
is.na<-
lapply(myfiles, within, is.na(V3) <- V2 < 50)
The result
[[1]]
V1 V2 V3
1 10001 33 NA
2 30001 65 0.0991478
3 50001 54 0.1564400
[[2]]
V1 V2 V3
1 10001 62 0.085526
2 30001 74 0.153664
3 50001 71 0.102096
[[3]]
V1 V2 V3
1 10001 49 NA
2 30001 65 0.169615
3 50001 61 0.070896
Using ifelse on list
Assuming your data is in a data.frame
you could use apply to loop over each row and check if any of the columns you are interested have a 1:
FatherDisease1 <- paste("n_20107_0_", 0:2, sep = "")
df$FatherCAD_0_0 <- apply(df, 1, function(x) as.integer(any(x[FatherDisease1] == 1)))
df
# n_20107_0_0 n_20107_0_1 n_20107_0_2 FatherCAD_0_0
#1 NA NA NA NA
#2 7 1 8 1
#3 4 6 1 1
Data:
df <- structure(list(n_20107_0_0 = c(NA, 7L, 4L), n_20107_0_1 = c(NA,
1L, 6L), n_20107_0_2 = c(NA, 8L, 1L)), .Names = c("n_20107_0_0",
"n_20107_0_1", "n_20107_0_2"), row.names = c(NA, -3L), class = "data.frame")
Ifelse statement to add NA to list
t(sapply(list_i1,`length<-`,max(lengths(list_i1))))
[,1] [,2] [,3]
[1,] 35 61 NA
[2,] 2 11 13
[3,] 10 15 35
[4,] 35 44 78
[5,] 22 86 101
where
list_i1 = list(c(35,61),c(2,11,13),c(10,15,35),c(35,44,78),c(22,86,101))
Is there any difference between using multiple if statements and else if statements?
Yes, potentially. Consider this (C#, Java, whatever):
int x = GetValueFromSomewhere();
if (x == 0)
{
// Something
x = 1;
}
else if (x == 1)
{
// Something else...
}
vs this:
int x = GetValueFromSomewhere();
if (x == 0)
{
// Something
x = 1;
}
if (x == 1)
{
// Something else...
}
In the first case, only one of "Something" or "Something else..." will occur. In the second case, the side-effects of the first block make the condition in the second block true.
Then for another example, the conditions may not be mutually exclusive to start with:
int x = ...;
if (x < 10)
{
...
}
else if (x < 100)
{
...
}
else if (x < 1000)
{
...
}
If you get rid of the "else" here, then as soon as one condition has matched, the rest will too.
ifelse() and if else given different results in dplyr mutate() for a time variable
Apparently, you do not understand ifelse
. It is fundamentally different from if
and else
. The documentation clearly says "ifelse
returns a value with the same shape as test
" which is a vector of length one in your example. mutate
then recycles this.
Here is a simple example:
all(c(TRUE, TRUE))
#[1] TRUE
ifelse(all(c(TRUE, TRUE)), 1:2, 3:4) #test is vector of length 1
#[1] 1
ifelse(c(TRUE, FALSE), 1:2, 3:4) #test is vector of length 2
#[1] 1 4
I'd encourage you to study the source code of the ifelse
function, which should make it obvious why it behaves like this.
if else in a list comprehension
>>> xs = [22, 13, 45, 50, 98, 69, 43, 44, 1]
>>> [x+1 if x >= 45 else x+5 for x in xs]
[27, 18, 46, 51, 99, 70, 48, 49, 6]
Do-something if <condition>
, else do-something else.
Related Topics
Handling Dates When We Switch to Daylight Savings Time and Back
Detach All Packages While Working in R
Unique() for More Than One Variable
Get_Map Not Passing the API Key (Http Status Was '403 Forbidden')
Python's Xrange Alternative for R or How to Loop Over Large Dataset Lazilly
Using Grep to Help Subset a Data Frame
R Displays Numbers in Scientific Notation
Why Is Using '<<-' Frowned Upon and How to Avoid It
Export a Graph to .Eps File with R
Marker Mouse Click Event in R Leaflet for Shiny
Struggling with Integers (Maximum Integer Size)
Ggplot2: Changing the Order of Stacks on a Bar Graph