if else statement concatenation - R - r

This is a very common question: 1, 2, 3, 4, 5, and still I cannot find even an answer to my problem.
If a == 1, then do X.
If a == 0, then do Y.
If a == 0 and b == 1, then do Z.
Just to explain: the if else statements has to do Y if a==0 no matter the value of b. But if b == 1 and a == 0, Z will do additional changes to those already done by Y.
My current code and its error:
if (a == 1){
X
} else if(a == 0){
Y
} else if (a == 0 & b == 1){
Z}
Error in !criterion : invalid argument type

An else only happens if a previous if hasn't happened.
When you say
But if b == 1 and a == 0, Z will do additional changes to those already done by Y
Then you have two options:
## Option 1: nest Z inside Y
if (a == 1){
X
} else if(a == 0){
Y
if (b == 1){
Z
}
}
## Option 2: just use `if` again (not `else if`):
if (a == 1) {
X
} else if(a == 0) {
Y
}
if (a == 0 & b == 1) {
Z
}
Really, you don't need any else here at all.
## This will work just as well
## (assuming that `X` can't change the value of a from 1 to 0
if (a == 1) {
X
}
if (a == 0) {
Y
if (b == 1){
Z
}
}
Typically else is needed when you want to have a "final" action that is done only if none of the previous if options were used, for example:
# try to guess my number between 1 and 10
if (your_guess == 8) {
print("Congratulations, you guessed my number!")
} else if (your_guess == 7 | your_guess = 9) {
print("Close, but not quite")
} else {
print("Wrong. Not even close!")
}
In the above, else is useful because I don't want to have enumerate all the other possible guesses (or even bad inputs) that a user might enter. If they guess 8, they win. If they guess 7 or 9, I tell them they were close. Anything else, no matter what it is, I just say "wrong".
Note: this is true for programming languages in general. It is not unique to R.
However, since this is in the R tag, I should mention that R has if{}else{} and ifelse(), and they are different.
if{} (and optionally else{}) evaluates a single condition, and you can run code to do anything in {} depending on that condition.
ifelse() is a vectorized function, it's arguments are test, yes, no. The test evaluates to a boolean vector of TRUE and FALSE values. The yes and no arguments must be vectors of the same length as test. The result will be a vector of the same length as test, with the corresponding values of yes (when test is TRUE) and no (when test is FALSE).

I believe you want to include Z in the second condition like this:
if (a == 1){X}
else if(a == 0){
Y
if (b == 1){Z}
}

Related

Does the line break between "}" and "else" really matters?

It is clearly that the documentation of R clearly goes against having a break line between "}" and "else". However, it is odd that the first piece of codes works but the second one does not work (syntax error)
First program
x = 1
stupid_function = function(x){
if(x != 1){
print("haha")
}
else if( x == 1){
print("hihi")
}
}
stupid_function(x)
[1] "hihi"
Second program
x = 1
if(x != 1){
print("haha")
}
else if( x == 1){
print("hihi")
}
Error in source("~/.active-rstudio-document", echo = TRUE) :
~/.active-rstudio-document:6:3: unexpected 'else'
5: }
6: else
In the second program it sees a line at a time as it is typed in so at the point that the line with the } is typed in it cannot know that there will be further lines with an else so it assumes the statement is finished.
In the first case it can see all the code before it is run because it can see all the code in the function so it knows that the } has not finished the statement.
This line of argument works for an if/else but does not work in general. For example, this will produce an error when the function is
defined.
f <- function(x) {
x
* 2
}
Note that the if else need not be in a function for it to work. It just need to be in a continuous form or in a way to be expressed as a continuous block of code. One way is being in a function. The other is to write it in one line, or even ensure that there is no line break between the if block and the else block:
x <- 1
if(x != 1) print('haha') else print('hihi')
[1] "hihi"
More blocks of statements:
x <- 1
if(x != 1){
print("haha")
} else if( x == 1){ # Note how else begins immediatley after }
print("hihi")
}
[1] "hihi"
Note that you need to know when to put the line breaks whether in a function or outside of a function. Otherwise the code might fail or even give incorrect results.
Using subtraction:
x <- 1
x -
2
[1] -1
x <- 1
x
- 2
[1] -2
You need to know when/where to have the line breaks. Its always safe to have else follow the closing brace } of the previous if statement. ie:
if(...){
....
} else if(...){
....
} else {
...
}

Error in if (num < 0) { : missing value where TRUE/FALSE needed

y <- as.integer(readline(prompt ="Enter a number: "))
factorial = 1
if (y< 0){
print("Error")
} else if (y== 0)
{
print("1")
} else
{
for(i in 1:y) {
factorial = factorial * i
}
return(factorial)
}
wondering why this is giving:
Error in if (y< 0) { : missing value where TRUE/FALSE needed
is it cause the first line has data type NA_integer?
There are three possible ways to pass values to the if statement.
y <- 1
if (y > 0) print("more")
This one works as expected.
y <- 1:3
if (y > 0) print("ignores all but 1st element")
As the warning message will tell you, only the first element was used to evaluate it. You could use any or all to make this right.
y <- NA
if (y > 0) print("your error")
This case actually gives you your error. I would wager a bet that y is somehow NA. You will probably need to provide a reproducible example (with data and the whole shebang) if you'll want more assistance. Note also that it helps visually structure your code to improve readability.

Return result from multiple if statements

I'm trying to use multiple actions in if statement. For example:
x <- 1
if (x == 1) {
paste("First")
1*1 #multiple actions
} else if (x == 2) {
paste("Second")
2*2 } else {("Nothing")
}
[1] 1 #what I'm getting
[2] "First"
1 #what I want to get
In this case only the second part of the expressions was printed to the console.
Any ideas how can I run all actions between if and else if ?
All statements are running as intended. The value of a statement is only printed to the console if all these conditions are true:
The value isn't saved to a variable
The value isn't invisible
It's the result of the last statement in an expression
R is running in interactive mode
The reason things sometimes print is to help people interactively exploring data in the command line. Instead of type print(x), they can save a few keystrokes by just typing x. In summary, use print if you want to be sure it's printed:
x <- 1
if (x == 1) {
print("First")
print(1*1)
} else if (x == 2) {
print("Second")
print(2*2)
} else {
invisible("Nothing")
}
# [1] "First"
# [1] 1
You can use print or cat:
getResult <- function(x = 1) {
if (x == 1) {
cat("First", 1 * 1, "\n")
} else if (x == 2) {
print("Second")
print(2 * 2)
} else {
cat("Nothing\n")
}
}
getResult()
# First 1
getResult(2)
# [1] "Second"
# [1] 4

Count Sequential Occurrences of Value in Vector

Given a generic vector x (which could be numeric, character, factor, etc.), I need to be able to count the number of sequential occurrences of value, including singletons.
x <- c(0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1)
In this case, the following would be returned if value == 0.
[1] 1 1 2 3
This code below works, but it is very slow when x gets large. Does anyone know of a way to speed this up? I imagine there must be a clever vectorized way of doing this.
getSequential <- function(x, value) {
counts <- c()
last <- FALSE
for (i in 1:length(x)) {
if (last & x[i] == value) {
counts[length(counts)] <- counts[length(counts)] + 1
} else if (x[i] == value) {
counts <- c(counts, 1)
last <- TRUE
} else {
last <- FALSE
}
}
return(counts)
}
you can use rle
rle(x)$lengths[which(rle(x)$values==0)]
# 1 1 2 3
for speed, you could only run rle once:
x1 <- rle(x)
x1$lengths[which(x1$values==0)]
Well, the code is quite good. I doubt using rle and with or which together would increase speed of the algorithm (much).
My proposition:
counting(int[] input, int value) {
int[] len = int[size(input)](); \\assume worst case scenario
len[0] = 0;
int j = 0;
for (i = 0; i < size(input); i++) { \\2 unit operations
if (input[i] != value && len[j] == 0) \\followed relatively often, 3-4 unit operations (1-2 unit operations on this step)
continue; \\5 unit operations
else if (input[1] == value) \\also followed relatively often, 4 unit operations (on '&&' if first is false, second is not checked)
len[j]++; \\5 unit operations
else /*if (input[i] != value && len[j] != 0)*/ { \\4 unit operations (commented operation is not needed (only remaining possible outcome)
j++; \\5 unit operations
len[j] = 0; \\7 unit operations (access and substitution)
continue; \\8 unit operations
}
}
}
As you can see there are at most 8 unit operations, and at best 4-5. Worst case scenario is that there are n/2 paths that go through 8 operations, but most of the cases I suppose it would follow one of the 5 step path.
Well, perhaps rle and those other functions are better optimized, but question is, is it optimized for your problem? I recommend checking.

What does "&&" do?

I can't seem to find the resource I need. What does && do in a code that is comparing variables to determine if they are true? If there is a link with a list of the symbol comparisons that would be greatly appreciated.
example: Expresssion 1: r = !z && (x % 2);
In most programming languages that use &&, it's the boolean "and" operator. For example, the pseudocode if (x && y) means "if x is true and y is true."
In the example you gave, it's not clear what language you're using, but
r = !z && (x % 2);
probably means this:
r = (not z) and (x mod 2)
= (z is not true) and (x mod 2 is true)
= (z is not true) and (x mod 2 is not zero)
= (z is not true) and (x is odd)
In most programming languages, the operator && is the logical AND operator. It connects to boolean expressions and returns true only when both sides are true.
Here is an example:
int var1 = 0;
int var2 = 1;
if (var1 == 0 && var2 == 0) {
// This won't get executed.
} else if (var1 == 0 && var2 == 1) {
// This piece will, however.
}
Although var1 == 0 evaluates to true, var2 is not equals to 0. Therefore, because we are using the && operator, the program won't go inside the first block.
Another operator you will see ofter is || representing the OR. It will evaluate true if at least one of the two statements are true. In the code example from above, using the OR operator would look like this:
int var1 = 0;
int var2 = 1;
if (var1 == 0 || var2 == 0) {
// This will get executed.
}
I hope you now understand what these do and how to use them!
PS: Some languages have the same functionality, but are using other keywords. Python, e.g. has the keyword and instead of &&.
It is the logical AND operator
(&&) returns the boolean value true if both operands are true and returns false otherwise.
boolean a=true;
boolean b=true;
if(a && b){
System.out.println("Both are true"); // Both condition are satisfied
}
Output
Both are true
The exact answer to your question depends on the which language your are coding in. In R, the & operator does the AND operation pairwise over two vectors, as in:
c(T,F,T,F) & c(T,T,F,F)
#> TRUE FALSE FALSE FALSE
whereas the && operator operated only on the first element of each vector, as in:
c(T,F,T,F) && c(T,T,F,F)
#> TRUE
The OR operators (| and ||) behave similarly. Different languages will have different meanings for these operators.
In C && works like a logical and, but it only operates on bool types which are true unless they are 0.
In contrast, & is a bitwise and, which returns the bits that are the same.
Ie. 1 && 2 and 1 && 3 are true.
But 1 & 2 is false and 1 & 3 is true.
Let's imagine the situation:
a = 1
b = 2
if a = 1 && b = 2
return "a is 1 and b is 2"
if a = 1 && b = 3
return "a is 1 and b is 3"
In this situation, because a equals 1 AND b = 2, the top if block would return true and "a is 1 and b is 2" would be printed. However, in the second if block, a = 1, but b does not equal 3, so because only one statement is true, the second result would not be printed. && Is the exact same as just saying and, "if a is 1 and b is 1".

Resources