Search code examples
rdplyrvectorization

"Case_when" depending on the index of an element in R?


Vectorized operations tend to work so that a logic is applied to EVERY element of a vector.

However, let's assume I have a vector i.e.

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

I would like to apply a function, say, multiplication by 0.5 to every element except the first and the last element: I would like to multiply them by 0.3.

Is there a dplyr (or any other vectorized) way to do this?

I know that sapply with if-else structure would do the trick i.e.

sapply(seq(1:10), #I know seq() is not actually needed in this particular case
    function(i) {
        if(i == 1 | i == length(1:10)) {
            (1:10)[i]*0.3
        } else {
            (1:10)[i]*0.5
        }
    }
)

...but vectorized solution with an index dependent case_when would be nice.


Solution

  • Since you explicitly mentioned case_when in your title, one index dependent case_when solution could be:

    library(dplyr)
    
    x <- 1:10
    
    data.frame(x) %>%
      mutate(x_mult = case_when(
        row_number() == 1 | row_number() == n() ~ x * 3,
        TRUE ~ x * 5
      ))
    

    Output:

        x x_mult
    1   1      3
    2   2     10
    3   3     15
    4   4     20
    5   5     25
    6   6     30
    7   7     35
    8   8     40
    9   9     45
    10 10     30