Auch wenn in vielen Einführungen auf den ersten Seiten erwähnt wird, wie bequem doch die Arbeit wird, wenn man attach(DataFrame) schreibt, es ist gefährlich. Diese Funktion verändert den Suchpfad, das heißt es verändert die Art und Weise, wie (bei gegebenem Objektnamen) nach einem Objekt gesucht wird.
Für alle, die nicht genau wissen, was ein Suchpfad (searchpath) ist oder wie R nach dem richtigen Objekt sucht, wenn dessen Name im Code steht, bedeutet das:
Finger weg von dieser Funktion
... und alle anderen (also die, die es wissen ...) werden schon deshalb diese Funktion nicht verwenden.
(ich krame demnächst noch ein paar Beispiele raus, die zeigen, wie man sich ganz toll ins Knie schießen kann bei der Verwendung dieser wirklich bösen Funktion)
Womit kann ich mich vom ewigen Tippen von DataFrame$... erleichtern
Da gibt es einige sehr schmucke Möglichkeiten:
1. viele Funktionen haben einen Parameter data= (z.B. lm() und viele plot-Funktionen). Tauchen in den anderen Argumenten der Funktion irgendwelche Objeknamen auf z.B. var1, dann sucht R das passende Objekt zuerst in DataFrame, wenn als Parameter data=DataFrame angegeben wurde. (In diesem Fall wird also DataFrame$var1 als Objekt für den Namen var1 gefunden)
2. Ähnlich ist das bei den Funktionen with(), within() und transform().
Gruß, Jörg
bitte kein attach()
Re: bitte kein attach()
Für diejenigen die sich schlau machen wollen:Für alle, die nicht genau wissen, was ein Suchpfad (searchpath) ist oder wie R nach dem richtigen Objekt sucht, wenn dessen Name im Code steht [...]
- How-R-Searches-And-Finds-Stuff
- Kapitel Environments in Advanced R
Bitte immer ein reproduzierbares Minimalbeispiel angeben. Meinungen gehören mir und geben nicht die meines Brötchengebers wieder.
Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
.
Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
.
Re: bitte kein attach()
Hier noch einige englische Texte zu dem Thema:
https://google.github.io/styleguide/Rguide.xml
http://rforcats.net/#nonos
http://stackoverflow.com/questions/1006 ... se-instead
Jetzt, wie versprochen, zu den Beispielen - quasi die attach()-Gruselkammer. Der Datensatz BOD ist standardmäßig in R vorhanden.Wie man sieht, wurde keine Spalte B$xneu angelegt, sondern der Vektor xneu wurde in der globalen Enviroment angelegt. Um das genannte Ziel zu erreichen, hätte man doch wieder B$xneu <- demand + 100 schreiben müssen. Die sauberen Lösungen sehen so aus:
Zu jedem attach() muss ein detach() erfolgen. (Außer, man schließt ohnehin die gesamte R-Session.)
Selbst, wenn man detach() schreibt, heißt das noch lange nicht, dass es im Verlaufe eines Skriptes auch ausgeführt wird:Lässt man so ein Skript mehrfach hintereinander laufen, erfolgt immer wieder eine Maskierung der entsprechenden Objekte: die maskierten Objekte sind dann nicht mehr so einfach zu erreichen.
Handelt es sich um größere Objekte, kann man auf diese Weise auch sehr schön schnell den verfügbaren RAM restlos ausschöpfen.
Die saubere Lösung sieht in diesem Fall so aus:
Noch ein Beispiel:
Sollten hier bei der Ausgabe von demand nicht nur die Werte erscheinen, die größer als 11 sind (wegen subset(...))
Wahrscheinlich wollte hier jemand folgendes erledigen (dies ist die saubere Lösung):
... und noch eins:
Wenn man für den Zugriff auf B$Time durch das attach() nicht das B$... einsparen kann, dann ist die Anwendung schwierig. Das verquere an dieser Situation ist, dass sie abhängig davon ist, ob vor dem attach() ein Objekt im Workspace existiert, das den gleichen Namen hat, wie eine Spalte des Dataframes im Aufruf von attach()
Gruß, Jörg
https://google.github.io/styleguide/Rguide.xml
http://rforcats.net/#nonos
http://stackoverflow.com/questions/1006 ... se-instead
Jetzt, wie versprochen, zu den Beispielen - quasi die attach()-Gruselkammer. Der Datensatz BOD ist standardmäßig in R vorhanden.
Code: Alles auswählen
B <- BOD
attach(B)
xneu <- demand + 100 # in der Annnahme, dass eine neue Spalte im Dataframe B angelegt wird
detach(B)
B
Code: Alles auswählen
B$xneu <- B$demand + 100 ### oder
B$xneu <- with(B, demand + 100)
Selbst, wenn man detach() schreibt, heißt das noch lange nicht, dass es im Verlaufe eines Skriptes auch ausgeführt wird:
Code: Alles auswählen
B <- BOD
attach(B)
m <- lm(demnad ~ Time) # Schreibfehler ...
detach(B) # detach() wird nicht erreicht
Handelt es sich um größere Objekte, kann man auf diese Weise auch sehr schön schnell den verfügbaren RAM restlos ausschöpfen.
Die saubere Lösung sieht in diesem Fall so aus:
Code: Alles auswählen
B <- BOD
m <- lm(demnad ~ Time, data=B)
Code: Alles auswählen
B <- BOD
attach(B)
B <- subset(B, demand>11)
B
demand
detach(B)
Wahrscheinlich wollte hier jemand folgendes erledigen (dies ist die saubere Lösung):
Code: Alles auswählen
B <- BOD
B <- subset(B, demand>11)
Code: Alles auswählen
B <- BOD
Time <- "Es ist Zeit"
attach(B)
Time # kein einfacher Zugriff auf Spalte B$Time
B$Time # man benötigt für den Zugriff auf die Spalte doch wieder B$...
detach(B)
Gruß, Jörg