Bea*_*eld 4 functional-programming r apply
这不是一个真正的问题,但我想知道是否有更优雅的解决方案:
让我说我有一个向量vec <- rlnorm(10)
,我想对它应用一个非向量化的函数,例如exp
(忽略它被矢量化的那一刻),我可以做
sapply( vec, exp )
Run Code Online (Sandbox Code Playgroud)
但是当我想要应用的函数嵌套时,表达式变得不那么简单:
sapply( vec, function(x) exp( sqrt(x) ) )
Run Code Online (Sandbox Code Playgroud)
这种情况一直发生在我apply
和plyr
家人身上.
所以我的问题是,通常是一种优雅的方式来嵌套(或管道)函数而不明确定义(匿名)函数function(x){...}
?就像是
# notrun
sapply( vec, sqrt | exp )
Run Code Online (Sandbox Code Playgroud)
或类似的.
请参阅以下示例?Reduce
:
## Iterative function application:
Funcall <- function(f, ...) f(...)
## Compute log(exp(acos(cos(0))
Reduce(Funcall, list(log, exp, acos, cos), 0, right = TRUE)
Run Code Online (Sandbox Code Playgroud)
这是一个更简单的实现,具有略微不同的界面:
Compose <- function(x, ...)
{
lst <- list(...)
for(i in rev(seq_along(lst)))
x <- lst[[i]](x)
x
}
sapply(0, Compose, log, exp, acos, cos)
Run Code Online (Sandbox Code Playgroud)
包functional包括一个Compose
函数。
library(functional)
id <- Compose(exp, log)
id(2) # 2
Run Code Online (Sandbox Code Playgroud)
它的实现很简单,可以包含在您的源代码中,例如,如果您不需要函数包中的其余内容。
R> Compose
function (...)
{
fs <- list(...)
if (!all(sapply(fs, is.function)))
stop("Argument is not a function")
function(...) Reduce(function(x, f) f(x), fs, ...)
}
<environment: namespace:functional>
Run Code Online (Sandbox Code Playgroud)