user113156
user113156

Reputation: 7107

map and lapply to call functions stored in a character string

I have some time series data that I want to lapply or map over some functions. For example, I want to apply the two functions in funcs to the data.

Code:

library(tsfeatures)
funcs = c("ac_9", "unitroot_pp")
map(funcs, ~function(x) tsfeatures(data$close, features = x))

What currently works is:

tsfeatures(data$close, features = "ac_9")
tsfeatures(data$close, features = "unitroot_pp")

I want to store the function name as a character string and call it.

Data:

data <- structure(c(59.25, 59.25, 59.26, 59.27, 59.26, 59.29, 59.28, 
59.29, 59.31, 59.34, 59.33, 59.34, 59.38, 59.39, 59.35, 59.42, 
59.44, 59.45, 59.46, 59.47, 59.47, 59.48, 59.49, 59.47, 59.51, 
59.51, 59.53, 59.55, 59.6, 59.59, 59.58, 59.6, 59.58, 59.56, 
59.54, 59.51, 59.52, 59.54, 59.6, 59.62, 59.57, 59.57, 59.65, 
59.25, 59.27, 59.3, 59.28, 59.29, 59.3, 59.31, 59.31, 59.35, 
59.35, 59.35, 59.38, 59.39, 59.4, 59.42, 59.46, 59.47, 59.46, 
59.47, 59.49, 59.48, 59.49, 59.5, 59.51, 59.54, 59.52, 59.56, 
59.6, 59.6, 59.62, 59.61, 59.6, 59.63, 59.66, 59.55, 59.53, 59.56, 
59.61, 59.65, 59.62, 59.58, 59.66, 59.71, 59.25, 59.24, 59.26, 
59.26, 59.25, 59.26, 59.27, 59.26, 59.3, 59.31, 59.33, 59.32, 
59.36, 59.34, 59.34, 59.41, 59.41, 59.42, 59.45, 59.46, 59.47, 
59.47, 59.47, 59.47, 59.5, 59.49, 59.52, 59.55, 59.54, 59.57, 
59.57, 59.56, 59.56, 59.53, 59.5, 59.49, 59.51, 59.53, 59.56, 
59.55, 59.55, 59.56, 59.62, 59.25, 59.27, 59.27, 59.27, 59.29, 
59.28, 59.28, 59.31, 59.35, 59.33, 59.33, 59.38, 59.39, 59.34, 
59.42, 59.44, 59.45, 59.46, 59.47, 59.47, 59.48, 59.48, 59.47, 
59.5, 59.51, 59.52, 59.55, 59.6, 59.58, 59.58, 59.61, 59.58, 
59.56, 59.54, 59.51, 59.52, 59.54, 59.61, 59.62, 59.57, 59.57, 
59.66, 59.67), .Dim = c(43L, 4L), .Dimnames = list(NULL, c("open", 
"high", "low", "close")), index = structure(c(1588972675, 1588972680, 
1588972740, 1588972800, 1588972860, 1588972920, 1588972980, 1588973040, 
1588973100, 1588973160, 1588973220, 1588973280, 1588973340, 1588973400, 
1588973460, 1588973520, 1588973580, 1588973640, 1588973700, 1588973760, 
1588973820, 1588973880, 1588973940, 1588974000, 1588974060, 1588974120, 
1588974180, 1588974240, 1588974300, 1588974360, 1588974420, 1588974480, 
1588974540, 1588974600, 1588974660, 1588974720, 1588974780, 1588974840, 
1588974900, 1588974960, 1588975020, 1588975080, 1588975140), tzone = "", tclass = c("POSIXct", 
"POSIXt")), class = c("xts", "zoo"))

EDIT:

When I pass:

> newFunction <- function(x){
+   tsfeatures(data$close, features = x)
+ }
> 
> map(funcs, ~newFunction(.x))
[[1]]
# A tibble: 1 x 1
   ac_9
  <dbl>
1 0.385

[[2]]
# A tibble: 1 x 1
  unitroot_pp
        <dbl>
1      -0.899

Upvotes: 0

Views: 40

Answers (1)

Konrad Rudolph
Konrad Rudolph

Reputation: 545528

You’re using map from the ‘purrr’ package incorrectly.

You need to pass the mapper function either as a function, or as a formula. You are attempting to pass a formula containing a function.

To fix this, write either

map(funcs, function(x) tsfeatures(data$close, features = x))

or

map(funcs, ~ tsfeatures(data$close, features = .x))

Likewise when using lapply, but that only works with a function, not with a formula.

Upvotes: 1

Related Questions