33 votes

cacher des fonctions personnelles dans R

J'ai quelques fonctions pratiques dans mon .Rprofile, comme celle-ci fonction pratique pour retourner la taille des objets en mémoire . Parfois j'aime nettoyer mon espace de travail sans redémarrer et je le fais avec rm(list=ls()) qui supprime tous mes objets créés par l'utilisateur ET mes fonctions personnalisées. J'aimerais vraiment ne pas faire sauter mes fonctions personnalisées.

L'un des moyens de contourner ce problème semble être de créer un paquet avec mes fonctions personnalisées afin que celles-ci se retrouvent dans leur propre espace de noms. Ce n'est pas particulièrement difficile, mais existe-t-il un moyen plus simple de s'assurer que les fonctions personnalisées ne sont pas tuées par rm() ?

36voto

Gavin Simpson Points 72349

Combinez attach y sys.source de s'introduire dans un environnement et d'attacher cet environnement. Ici, j'ai deux fonctions dans le fichier my_fun.R :

foo <- function(x) {
    mean(x)
}

bar <- function(x) {
    sd(x)
}

Avant que je ne charge ces fonctions, elles ne sont évidemment pas trouvées :

> foo(1:10)
Error: could not find function "foo"
> bar(1:10)
Error: could not find function "bar"

Créer un environnement et y déposer le fichier :

> myEnv <- new.env()
> sys.source("my_fun.R", envir = myEnv)

Toujours pas visible car nous n'avons rien attaché.

> foo(1:10)
Error: could not find function "foo"
> bar(1:10)
Error: could not find function "bar"

et lorsque nous le faisons, ils sont visibles, et parce que nous avons attaché une copie de l'environnement au chemin de recherche, les fonctions survivent en étant rm() -.. :

> attach(myEnv)
> foo(1:10)
[1] 5.5
> bar(1:10)
[1] 3.027650
> rm(list = ls())
> foo(1:10)
[1] 5.5

Je pense toujours que vous seriez mieux avec votre propre paquet personnel, mais ce qui précède pourrait suffire en attendant. N'oubliez pas que la copie sur le chemin de recherche n'est que cela, un copie . Si les fonctions sont assez stables et que vous ne les éditez pas, alors ce qui précède peut être utile, mais c'est probablement plus de tracas que cela n'en vaut la peine si vous développez les fonctions et les modifiez.

Une deuxième option est de les nommer tous .foo plutôt que foo como ls() ne renverra pas d'objets nommés ainsi, sauf si l'argument all = TRUE est réglé :

> .foo <- function(x) mean(x)
> ls()
character(0)
> ls(all = TRUE)
[1] ".foo"         ".Random.seed"

22voto

G. Grothendieck Points 40825

Voici deux façons de procéder :

1) Faites en sorte que chacun de vos noms de fonction commence par un point., par ex. .f au lieu de f . ls ne répertorie pas ces fonctions, à moins que vous n'utilisiez ls(all.names = TRUE) par conséquent, ils ne seront pas transmis à votre rm commandement.

ou,

2) Mettez ceci dans votre .Rprofile

attach(list(
   f = function(x) x, 
   g = function(x) x*x
), name = "MyFunctions")

Les fonctions apparaîtront sous la forme d'un composant nommé "MyFunctions" dans votre liste de recherche plutôt que dans votre espace de travail et ils seront accessibles presque de la même manière que s'ils étaient dans votre espace de travail. search() affichera votre liste de recherche et ls("MyFunctions") listera les noms des fonctions que vous avez attachées. Puisqu'elles ne se trouvent pas dans votre espace de travail, la fonction rm que vous utilisez normalement ne les supprimera pas. Si vous souhaitez les supprimer, utilisez detach("MyFunctions") .

10voto

Dirk Eddelbuettel Points 134700

La réponse de Gavin est merveilleuse, et je viens de l'upvooter. Juste pour être complet, laissez-moi en ajouter une autre :

R> q("no")

suivi par

M-x R

pour créer une nouvelle session --- qui relit le fichier .Rprofile . Facile, rapide et bon marché.

À part cela, les forfaits privés sont la meilleure solution à mes yeux.

3voto

Richie Cotton Points 35365

Une autre alternative : garder les fonctions dans un fichier séparé qui est sourcé à l'intérieur de .RProfile . Vous pouvez re-sourcer le contenu directement à partir de R à votre guise.

2voto

user624941 Points 11

Je trouve que mon environnement R est souvent encombré de divers objets lorsque je crée ou débogue une fonction. Je voulais un moyen efficace de garder l'environnement libre de ces objets tout en conservant les fonctions personnelles.

La fonction simple ci-dessous était ma solution. Elle fait 2 choses : 1) elle supprime tous les objets non fonctionnels qui ne commencent pas par une majuscule et ensuite 2) elle sauvegarde l'environnement dans un fichier RData.

(nécessite le paquet R.oo)

cleanup=function(filename="C:/mymainR.RData"){  
library(R.oo)  
# create a dataframe listing all personal objects
everything=ll(envir=1)
#get the objects that are not functions
nonfunction=as.vector(everything[everything$data.class!="function",1])
#nonfunction objects that do not begin with a capital letter should be deleted
trash=nonfunction[grep('[[:lower:]]{1}',nonfunction)]
remove(list=trash,pos=1)
#save the R environment
save.image(filename)
print(paste("New, CLEAN R environment saved in",filename))
}

Pour utiliser cette fonction, il faut toujours respecter 3 règles :
1) Garder toutes les données externes à R.
2) Utiliser des noms qui commencent par une majuscule pour les objets non fonctionnels que je veux garder disponibles en permanence.
3) Les fonctions obsolètes doivent être supprimées manuellement avec rm.

Évidemment, ce n'est pas une solution générale pour tout le monde... et potentiellement désastreuse si vous ne respectez pas les règles 1 et 2. Mais elle présente de nombreux avantages : a) la crainte que mes données soient détruites par cleanup() m'oblige à utiliser R exclusivement comme un processeur et non comme une base de données, b) mon environnement R principal est si petit que je peux le sauvegarder en tant que pièce jointe à un e-mail, c) les nouvelles fonctions sont automatiquement sauvegardées (je n'ai pas à gérer manuellement une liste de fonctions personnelles) et d) toutes les modifications apportées aux fonctions préexistantes sont conservées. Bien sûr, le meilleur avantage est le plus évident... je n'ai pas à passer du temps à faire ls() et à examiner les objets pour décider s'ils doivent être rm'd.

Même si vous ne vous intéressez pas aux spécificités de mon système, la fonction "ll" de R.oo est très utile pour ce genre de choses. Elle peut être utilisée pour implémenter à peu près n'importe quel ensemble de règles de nettoyage qui correspondent à votre style de programmation personnel.

Patrick Mohr

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