web-dev-qa-db-fra.com

Quelles sont les façons de modifier une fonction dans R?

Disons que nous avons la fonction suivante:

foo <- function(x)
{
    line1 <- x
    line2 <- 0
    line3 <- line1 + line2
    return(line3)
}

Et que nous voulons changer la deuxième ligne pour qu'elle soit:

    line2 <- 2

Comment feriez-vous cela?

Une façon consiste à utiliser

fix(foo)

Et changez la fonction.

Une autre façon consiste à simplement réécrire la fonction.

Y a-t-il un autre moyen? (Rappelez-vous, la tâche consistait à modifier uniquement la deuxième ligne)

Ce que j'aimerais, c'est d'une certaine manière représenter la fonction comme un vecteur de chaînes (enfin, des caractères), puis changer l'une de ses valeurs, puis la transformer à nouveau en fonction.

48
Tal Galili

Ou jetez un œil à la fonction de débogage trace(). Ce n'est probablement pas exactement ce que vous recherchez, mais il vous permet de jouer avec les changements et il a la fonctionnalité Nice que vous pouvez toujours revenir à votre fonction d'origine avec untrace(). trace() fait partie du paquet base et est livré avec une page d'aide agréable et complète.

Commencez par appeler as.list (body(foo)) pour voir toutes les lignes de votre code.

as.list(body(foo))
[[1]]
`{`

[[2]]
line1 <- x

[[3]]
line2 <- 0

[[4]]
line3 <- line1 + line2

[[5]]
return(line3)

Ensuite, vous définissez simplement ce qu'il faut ajouter à votre fonction et où le placer en définissant les arguments dans trace().

trace (foo, quote(line2 <- 2), at=4)
foo (2)
[1] 4

J'ai dit au début que trace() n'était peut-être pas exactement ce que vous cherchiez car vous n'avez pas vraiment changé votre troisième ligne de code et au lieu de cela simplement réattribué la valeur à l'objet line2 Dans la ligne de code suivante insérée. Cela devient plus clair si vous imprimez le code de votre fonction maintenant tracée

body (foo)
{
    line1 <- x
    line2 <- 0
    {
        .doTrace(line2 <- 2, "step 4")
        line3 <- line1 + line2
    }
    return(line3)
}
24
mropa
> body(foo)[[3]] <- substitute(line2 <- 2)
> foo
function (x) 
{
    line1 <- x
    line2 <- 2
    line3 <- line1 + line2
    return(line3)
}

(Le "{" est body (foo) [[1]] et chaque ligne est un élément successif de la liste.)

36
42-

fix est le meilleur moyen que je connaisse de le faire, bien que vous puissiez également utiliser edit et le réaffecter:

foo <- edit(foo)

C'est ce que fix fait en interne. Vous pouvez le faire si vous souhaitez réaffecter vos modifications à un nom différent.

20
Shane

fixInNamespace est comme fix, pour les fonctions d'un package (y compris celles qui n'ont pas été exportées).

15
Richie Cotton

Vous pouvez utiliser la fonction 'body'. Cette fonction renverra le corps de la fonction:

fnx = function(a, b) { return(a^2 + 7*a + 9)}
body(fnx)
# returns the body of the function

Donc, un bon moyen de "modifier" une fonction consiste à utiliser "corps" sur le côté gauche d'une instruction d'affectation:

body(fnx) = expression({a^2 + 11*a + 4})
8
doug