bitte kein attach()

Wie rufe ich R-Funktionen auf, wie selektiere ich Daten, ich weiß nicht genau ....

Moderatoren: EDi, jogo

Antworten
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

bitte kein attach()

Beitrag von jogo »

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
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: bitte kein attach()

Beitrag von EDi »

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 [...]
Für diejenigen die sich schlau machen wollen:
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
Bild.
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: bitte kein attach()

Beitrag von jogo »

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.

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
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:

Code: Alles auswählen

B$xneu <- B$demand + 100 ### oder
B$xneu <- with(B, demand + 100)
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:

Code: Alles auswählen

B <- BOD
attach(B)
m <- lm(demnad ~ Time)  # Schreibfehler ...
detach(B)  # detach() wird nicht erreicht
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:

Code: Alles auswählen

B <- BOD
m <- lm(demnad ~ Time, data=B)
Noch ein Beispiel:

Code: Alles auswählen

B <- BOD
attach(B)
B <- subset(B, demand>11)
B
demand
detach(B)
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):

Code: Alles auswählen

B <- BOD
B <- subset(B, demand>11)
... und noch eins:

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)
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
Antworten