Search code examples
ranonymous-function

replacing elements of character vector with anonymous function does not return full vector


I'm confused by the following behaviour:

y <- letters |>
  (\(x) x[stringr::str_which(x, "a|e")] <- c("1", "2"))()

which returns [1] "1" "2"

However, I would have expected this function to return the full vector of letters just with a and e being replaced.

What is going on here?

Note: this might look like an overcomplicated way of achieving things, but I'm stuck by taking a real character vector, detect the elements that follow a certain pattern and then in a vectorized way replace the elements by different elements.

So in this example a <- c("Q1", "Q6", "Q6") I want to replace the first occurrence of "Q6" with "a" and the second one with "b".


Solution

  • The return value of a function is the value of the last expression executed inside it.

    Your function only contains a single expression: the subset assignment, which R treats as a call to the function `[<-`. This is a so-called replacement function, and all replacement functions return the value that was passed into it, i.e. c("1", "2") in your case.

    Therefore this is the value of your anonymous function.

    To return the entire vector, you need to make that vector the last expression of the function. You can do this by putting just the vector variable as the last expression into the anonymous function:

    y <- letters |>
      (\(x) {
        x[stringr::str_which(x, "a|e")] <- c("1", "2")
        x
      })()