How to validate a condition in a for loop

Viewed 105

I am studying R end Data Science. In a question, I need to validate if a number in an array is even.

My code:

vetor <- list(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))

for (i in vetor) {
    if (i %% 2 == 0) {
      print(i)
    } 
}

But the result is a warning message:

Warning message:
In if (i%%2 == 0) { :
  a condição tem comprimento > 1 e somente o primeiro elemento será usado

Translating:

The condition has a length > 1 and only the first element will be used.

What I need, that each element in a list be verified if is even, and if true, then, print it.

In R, how can I do it?

2 Answers

The wrapper for list is not needed

vetor <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

running the OP's code

for (i in vetor) {
    if (i %% 2 == 0) {
      print(i)
    } 
}

#[1] 2
#[1] 4
#[1] 6
#[1] 8
#[1] 10

These are vectorized operations. We don't need a loop

vetor[vetor %% 2 == 0]
#[1]  2  4  6  8 10

When we wrap the vector with list, it returns a list of length 1 and the unit will be the whole vector. The for loop in R is a for each loop and not the traditional counter controlled 3 part expression loop. So, the i will be the whole vetor vector.

Because if/else expects a single element and not a vector of length greater than 1, it results in the warning message

Or if we want to store it in a list with each element of length 1, use as.list

vetor <- as.list(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))

Let's break down your code and dig into each step to see what happened ...


You should notice that vetor is a list, i.e.,

> vetor
[[1]]
 [1]  1  2  3  4  5  6  7  8  9 10

In this case, the iterator i in vetor denotes the array in vetor, which can be seen from

> for (i in vetor) {
+   str(i)
+ }
 num [1:10] 1 2 3 4 5 6 7 8 9 10

Therefore, when you have condition i%%2==0, you are indeed running

> for (i in vetor) {
+   print(i %% 2 == 0)
+ }
 [1] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE

which is not a single logic value as a condition for if ... else ... state. That is the reason you got the warnings.


Regarding the workaround, you can refer to @akrun's answer, which could help you a lot

Related