Nadaraj
Nadaraj

Reputation: 579

Couldn't reduce the looping variable inside the "for" loop in R

I have a for loop to do a matrix manipulation in R. For some checks are true i need to come to the same row again., means i need to be reduced by 1.

for(i in 1:10)
{
    if(some chk)
    {
    i=i-1
    }
}

Actually i is not reduced for me. For an example in 5th row i'm reducing the i to 4, so again it should come as 5, but it is coming as 6. Please advice.

My intention is: Checking the first column values of a matrix, if I find any duplicate value, I take the second column value and append with the first row's second column and remove the duplicate row. So, when I'm removing a row I do not need increase the i in while loop. (This is just a map reduce method, append values of same key)

Upvotes: 0

Views: 235

Answers (1)

Konrad Rudolph
Konrad Rudolph

Reputation: 545628

Variables in R for loops are read-only, you cannot modify them. What you have written would be solved completely differently in normal R code – the exact solution depending on the actual problem, there isn’t a generic, direct replacement (except by replacing the whole thing with a while loop but this is both ugly and probably unnecessary).

To illustrate this, consider these two typical examples.

  1. Assume you want to filter all duplicated elements from a list. Instead of looping over the list and copying all duplicated elements, you can use the duplicated function which tells you, for each element, whether it’s a duplicate.

    Secondly, you use standard R subsetting syntax to select just those elements which are not a duplicate:

    x = x[! duplicated(x)]
    

    (This example works on a one-dimensional vector or list, but it can be generalised to more dimensions.)

  2. For a more complex case, let’s say that you have a vector of numbers and, for every even number in the vector, you want to double the preceding number (this is highly artificial but in signal processing you might face similar problems). In other words:

    input = c(1, 3, 2, 5, 6, 7, 1, 8)
    output = ???
    output
    # [1]  1  6  2 10  6  7  2  8
    

    … we want to fill in ???. In the first step, we check which numbers are even:

    even = input %% 2 == 0
    # [1] FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE
    

    Next, we shift the result down – because we want to know whether the next number is even – by removing the first element, and appending a dummy element (FALSE) at the end.

    even = c(even[-1], FALSE)
    # [1] FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE
    

    And now we can multiply just these inputs by two:

    output = input
    output[even] = output[even] * 2
    

    There, done.

Upvotes: 3

Related Questions