Search code examples
rfunctionreducesubstitutionquote

Collapse a vector of function calls in to one line, separating each call with &, using substitute and Reduce?


I'm trying to construct the function call str_detect(words, "a") & str_detect(words, "e") & str_detect(words, "i") & str_detect(words, "o") & str_detect(words, "u") without doing all of that painful typing. I know that this is not a good way to solve the problem in question, but after doing a poor job of solving it a better way, I decided to try to do it like this just to see if I could learn anything from it.

My attempt was as follows:

library(stringr)
funList <- sapply(c("a", "e", "i", "o", "u"), function(y) substitute(str_detect(words, x), list(x=y)))
Reduce(function(a,b) paste(a, "&", b), funList)

This almost worked. funList is pretty much what we expect:

> funList
$a
str_detect(words, "a")

$e
str_detect(words, "e")

$i
str_detect(words, "i")

$o
str_detect(words, "o")

$u
str_detect(words, "u")

But the final line gives some very unexpected output, presumably due to how R constructs function calls:

> Reduce(function(a,b) paste(a, "&", b), funList)
[1] "str_detect & str_detect & str_detect & str_detect & str_detect"
[2] "words & words & words & words & words"                         
[3] "a & e & i & o & u"

Can this be fixed to give the intended function call? I've tried a few tricks like throwing the quote function around, but I've not achieved anything.


Solution

  • This is a really bad general approach. You probably also don't need to do this.

    However, it's quite easy if you continue to compute on the language and utilize that operators are actually parsed as functions:

    funList <- lapply(c("a", "e", "i", "o", "u"), function(y) substitute(str_detect(words, x), list(x=y)))
    Reduce(function(a, b) substitute(`&`(a, b), list(a = a, b = b)), funList)
    #str_detect(words, "a") & str_detect(words, "e") & str_detect(words, 
    #    "i") & str_detect(words, "o") & str_detect(words, "u")