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.
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)
}
> 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.)
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.
fixInNamespace
est comme fix
, pour les fonctions d'un package (y compris celles qui n'ont pas été exportées).
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})