1
votes

I am attempting to compute a moving median on a variable contained within a data.frame using dplyr. The problem I am running into is that the function that I am passing into rollapply() has the same name as a variable in the original data.frame. For example:

df <- data.frame(median = seq(1:100))

df %>%
  mutate(ln_median = log(median)) %>%
  mutate(ln_median_10 = rollapply(ln_median, 5, median))

Generates the error message:

Error in eval(substitute(expr), envir, enclos) : '1:100' is not a function, character or symbol

The underlying cause is that the median in the rollapply() is resolving to the variable in the data.frame and not the function "median". I have been able to get around this with the following code:

df %>% mutate(ln_median = log(median)) %>%
       mutate(ln_median_10 = rollapply(ln_median, 5, function(a) median(a), fill = NA))

That is, by wrapping the median function in order to suppress it from being interpreted as a variable within the data.frame.

Is there a more elegant way of achieving the same thing?

3
I copied your code and got a different error: "Column ln_median_10 must be length 100 (the number of rows) or one, not 96". I fixed by adding the fill = NA parameter to rollapplylebelinoz
Which package is rollapply from? is it zoo?acylam

3 Answers

1
votes

have you tried to pass the function name in as

stats::median
0
votes

As @lebelinoz mentioned in the comments, you can use fill = NA to solve the unequal length error. Not able to reproduce your error though. Also note that mutate allows you to use a variable you have just created within the same function. So no need for the second mutate:

library(zoo)

df %>%
  mutate(ln_median = log(median),
         ln_median_10 = rollapply(ln_median, 5, median, fill = NA))
0
votes

If it was really the issue (but I can't reproduce it either), you could use match.fun("median") instead of median