38 votes

fonctions de niveau supérieur dans R - existe-t-il un opérateur de composition officiel ou une fonction curry?

Je peux créer un composer opérateur dans R:

 `%c%` = function(x,y)function(...)x(y(...)) 

Pour être utilisée comme ceci:

 > numericNull = is.null %c% numeric
 > numericNull(myVec)
 [2] TRUE FALSE

mais je voudrais savoir si il y a un officiel ensemble de fonctions pour faire ce genre de chose et d'autres opérations telles que le lancer dans R. en grande partie c'est pour réduire le nombre de tranches, fonction de mots-clés, etc dans mon code.

Mon curry de la fonction:

> curry=function(...){
    z1=z0=substitute(...);z1[1]=call("list");
    function(...){do.call(as.character(z0[[1]]),
                          as.list(c(eval(z1),list(...))))}}
> p = curry(paste(collapse=""))
> p(letters[1:10])
[1] "abcdefghij"

C'est particulièrement agréable pour, par exemple, d'agrégation:

> df = data.frame(l=sample(1:3,10,rep=TRUE), t=letters[1:10])
> aggregate(df$t,df["l"],curry(paste(collapse="")) %c% toupper)
  l    x
1 1  ADG
2 2  BCH
3 3 EFIJ

Je la trouve beaucoup plus élégant et modifiable que:

> aggregate(df$t, df["l"], function(x)paste(collapse="",toupper(x)))
  l    x
1 1  ADG
2 2  BCH
3 3 EFIJ

Fondamentalement, je veux savoir a déjà été fait pour la R?

28voto

Shane Points 40885

Ces deux fonctions existent réellement dans l' roxygen package (voir le code source ici) de Peter Danenberg (était à l'origine basée sur Byron Ellis est solution sur R de l'Aide):

Curry <- function(FUN,...) {
  .orig = list(...);
  function(...) do.call(FUN,c(.orig,list(...)))
}

Compose <- function(...) {
  fs <- list(...)
  function(...) Reduce(function(x, f) f(x),
                       fs,
                       ...)
}

Remarque l'utilisation de l' Reduce de la fonction, qui peut être très utile lorsque vous essayez de faire de la programmation fonctionnelle dans R. Voir ?Réduire pour plus de détails (qui couvre également d'autres fonctions comme l' Map et Filter).

Et votre exemple de Curry (légèrement différente en cela de l'utilisation):

> library(roxygen)
> p <- Curry(paste, collapse="")
> p(letters[1:10])
[1] "abcdefghij"

Voici un exemple pour montrer l'utilité de l' Compose (application des trois fonctions différentes de lettres):

> Compose(function(x) x[length(x):1], Curry(paste, collapse=""), toupper)(letters)
[1] "ZYXWVUTSRQPONMLKJIHGFEDCBA"

Et votre dernier exemple pourrait fonctionner comme ceci:

> aggregate(df[,"t"], df["l"], Compose(Curry(paste, collapse=""), toupper))
  l    x
1 1  ABG
2 2 DEFH
3 3  CIJ

Enfin, voici une façon de faire la même chose avec plyr (peut aussi facilement être fait avec by ou aggregate comme déjà indiqué):

> library(plyr)
> ddply(df, .(l), function(df) paste(toupper(df[,"t"]), collapse=""))
  l   V1
1 1  ABG
2 2 DEFH
3 3  CIJ

2voto

Richie Cotton Points 35365

Il y a une fonction appelée Curry dans le paquetage roxygen .
Trouvé via cette conversation sur l’archive R Mail.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X