当前位置: 动力学知识库 > 问答 > 编程问答 >

functional programming - How to concatenate/compose functions in R?

问题描述:

Often I want to do something like the following:

sapply(sapply(x, unique),sum)

Which I can also write as:

sapply(x, function(y) sum(unique(y)))

But I don't like to write out the lambda each time. So is there some kind of function that lets me write?

sapply(x, concat(sum,unique))

And concat just concatenates the two functions, thus creates a new one, which executes one after the other.

网友答案:

For this you can use the Compose function in the functional package, which is available on CRAN.:

library(functional)
sapply(x, Compose(unique,sum))
网友答案:

More on Curry'ing and Composing

There is partial in package pryr which achieves roughly the same as Curry in package functional but in a different way.

(Curry creates a list of arguments and feeds it to do.call. partial literally creates a new function which calls the first function with default arguments set.)

In this discussion in R-devel, Luke Tierney points out some problems with Curry ("This has quite different behavior with respect to evaluation/lazy evaluation than an analogous anonymous function. In addition, do.call has some fairly strange aspect so it with respect to how it interacts with sys.xyz functions, and does not do what you want in many cases I care about when quote = FALSE, as is the default. Adding this would create more problems than is solves."). These issues (however infrequently they might arise) are not a concern with partial.

Other approaches to currying / partial function application:

wargs in package dostats (similar to partial but has something distinctive:

wargs(mean, na.rm=TRUE)(c(1:5, NA), na.rm=FALSE)
# this works and gives NA as answer, so na.rm=FALSE overrides na.rm=TRUE
# with partial, this would result in an error:
#### formal argument "na.rm" matched by multiple actual arguments

There is %but% in package operators but it doesn't work with generic functions. So ...

df <- data.frame(a=c(1:5,NA), b=c(NA, 2:6))
sapply(df, mean %but% list(na.rm=TRUE))
#  a  b 
# NA NA 
# ... but2
sapply(df, sd %but% list(na.rm=TRUE))
#        a        b 
# 1.581139 1.581139 

And it has a separate mechanism for setting logical arguments:

# from the help page
grep %but% "pf"     # grep, with perl and fixed set to TRUE

As for compose, there are identically named (but different) versions in both pryr and dostats: compose and %.% -- and both are different from functional:::Compose.

Finally, I would add that pryr includes f which one can conveniently use instead of function in anonymous functions.

网友答案:

Using magrittr

If we require(magrittr), then we can

sapply(x, . %>% unique %>% sum)

or even

x %>% sapply(. %>% unique %>% sum).
网友答案:

You could grow your own:

myfunc <- function(y) {
    yu <- unique(y)
    ys <- sum(yu)
    return(ys)
    }

Then

sapply(x, myfunc)
分享给朋友:
您可能感兴趣的文章:
随机阅读: