Home > Mobile >  Change numeric(0) to NA in pipe, but return unchanged otherwise
Change numeric(0) to NA in pipe, but return unchanged otherwise

Time:05-11

How to recode vector to NA if it is zero length (numeric(0)), but return the vector unchanged if not? Preferably in tidyverse using pipes.

My attempt:

library(tidyverse)
empty_numeric <- numeric(0)
empty_numeric |> 
    if_else(length(.) > 0, true =  NA, false = . )
#> Error: `condition` must be a logical vector, not a double vector.

CodePudding user response:

You can’t use a vectorised if_else here because its output is the same length as its input (i.e. always a single element). Instead, you’ll need to use conventional if. And neither will work with the built-in |> pipe since that restricts how the call can be formed (in particular, it only allows substituting the LHS into top-level arguments, and only once). By contrast, we need to repeat the LHS, and substitute it into a nested expression.

Using the ‘magrittr’ pipe operator works, however:

myvec %>% {if (length(.) > 0L) . else NA}

Or, if you prefer writing this using function call syntax:

myvec %>% `if`(length(.) > 0L, ., NA)

To be able to use the native pipe, we need to wrap the logic into a function:

na_if_null = function (x) {
    if (length(x) == 0L) as(NA, class(x)) else x
}

myvec |> na_if_null()

(The as cast is there to ensure that the return type is the same as the input type, regardless of the type of x.)

  • Related