Disons que j'ai un tas de fonctions, chacune avec quelque chose commeMyFunction.1
, etc. Je veux passer ces fonctions dans une autre fonction, qui imprime un petit rapport. Idéalement, j'aimerais pouvoir étiqueter des sections d'un rapport par lesquelles la fonction est utilisée pour générer les résultats.
Y a-t-il donc de bonnes façons d'obtenir le nom d'une fonction prédéfinie sous forme de chaîne?
Je voulais la même chose, et je me suis souvenu que library(foo)
n'avait pas besoin de guillemets, c'est ce qu'il fait:
package <- as.character(substitute(package))
Une autre approche consiste à passer les noms des fonctions dans votre fonction de rapport, puis à récupérer les fonctions elles-mêmes avec la commande get()
. Par exemple:
function.names <- c("which","all")
fun1 <- get(function.names[1])
fun2 <- get(function.names[2])
Ensuite, vous avez les noms dans votre vecteur de caractères d'origine et les fonctions ont de nouveaux noms tels que vous les avez définis. Dans ce cas, la fonction all
est maintenant appelée comme fun2
:
> fun2(c(TRUE, FALSE))
[1] FALSE
Ou, si vous voulez vraiment conserver les noms de fonction d'origine, affectez-les simplement localement avec la fonction assign:
assign(function.names[2], get(function.names[2]))
Si vous exécutez cette commande maintenant, vous vous retrouverez avec la fonction all
dans votre ".GlobalEnv"
. Vous pouvez le voir avec ls()
.
Cela peut conduire à parse(eval(...))
à quel point vous êtes ouvert à cette critique:
R> library(fortunes)
R> fortune("parse")
If the answer is parse() you should usually rethink the question.
-- Thomas Lumley
R-help (February 2005)
R>
Vos fonctions doivent donc être appelées MyFunction.1
etc pp?
Vous pouvez obtenir les arguments non évalués d'une fonction via match.call
. Par exemple:
> x <- function(y) print(match.call()[2])
> x(lm)
lm()
Lorsqu'une fonction est transmise en tant qu'objet, elle perd son nom. Voir, par exemple, les résultats des lignes suivantes:
str(lm)
lm
Vous pouvez obtenir les arguments et le corps de la fonction, mais pas le nom.
Ma suggestion serait de construire une liste nommée de fonctions, où le nom pourrait être imprimé:
> somefns <- list(lm=lm, aggregate=aggregate)
> str(somefns)
List of 2
$ lm :function (formula, data, subset, weights, na.action, method = "qr",
model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE,
contrasts = NULL, offset, ...)
$ aggregate:function (x, ...)
> somefns[[1]](dist ~ speed, data=cars)
Call:
somefns[[1]](formula = dist ~ speed, data = cars)
Coefficients:
(Intercept) speed
-17.58 3.93
> names(somefns)[[1]]
[1] "lm"
Je veux juste fournir un exemple pour montrer les avantages et les limites de ce problème:
Je veux "enregistrer" une fonction avec son nom, comme option qui serait utilisée dans une autre fonction:
R> foreach(..., .combine=test_fun) {...}
Le test_fun
est le nom de la fonction, et bien sûr
R> mode(test_fun)
[1] "function"
Quand je l'utilise dans foreach, j'ai juste besoin du nom de la fonction, tandis que test_fun
peut être une fonction existante (par exemple cbind
). Alors, test_fun
est attribué par
R> test_fun <- get('cbind')
ou
R> test_fun <- assign('cbind', get('cbind'))
Donc, vous avez la fonction ici
R> test_fun
function (..., deparse.level = 1)
.Internal(cbind(deparse.level, ...))
en fait, le nom d'origine ne peut pas être conservé, vous n'avez donc aucun moyen de convertir test_fun
retour à la chaîne "cbind"
.
R> deparse(substitute(test_fun))
[1] "test_fun"
J'ai malheureusement besoin d'analyser le code foreach donc je veux que le nom d'origine soit affiché dans la chaîne. Cela signifie que le seul moyen consiste à enregistrer 'cbind'
en tant que chaîne et la création d'un tel objet fonction n'apporte aucun avantage dans ce cas.
et ça:
deparse(quote(foo.bar))