Seite 1 von 1

fortune(312+343)

Verfasst: Do Jan 18, 2018 8:13 am
von bigben
Hallo Forum!


The fortune tellers sind offenbar nicht begeistert von der $-Notation zum Zugriff auf Dataframe-Spalten

Code: Alles auswählen

> fortune(312)

The problem here is that the $ notation is a
magical shortcut and like any other magic if used
incorrectly is likely to do the programmatic
equivalent of turning yourself into a toad.
   -- Greg Snow (in response to a user that wanted
      to access a column whose name is stored in y
      via x$y rather than x[[y]])
      R-help (February 2012)

Code: Alles auswählen

> fortune(343)

Sooner or later most R beginners are bitten by this
all too convenient shortcut. As an R newbie, think
of R as your bank account: overuse of $-extraction
can lead to undesirable consequences. It's best to
acquire the '[[' and '[' habit early.
   -- Peter Ehlers (about the use of $-extraction)
      R-help (March 2013)
Ich dilettiere seit Jahren mit dem $ herum und habe weder das Gefühl, jemals in eine Kröte verwandelt worden zu sein, noch sind mir die unwünschbaren Konsequenzen je bewusst geworden. Würdet Ihr mich erleuchten, warum eckige Klammern so viel besser sind als Dollars? 'Magical shortcut' klingt viel weniger süß als 'syntactic sugar'.

Viele Grüße,
Bernhard

Re: fortune(312+343)

Verfasst: Do Jan 18, 2018 10:55 am
von student
Hallo Bernhard,

seit Jahr und Tag nutze ich das $-Symbol und mir sind nie unerwünschte Effekte aufgefallen!

Re: fortune(312+343)

Verfasst: Do Jan 18, 2018 6:52 pm
von Curnen
Ich weiß nicht, was der offizielle Grund ist, aber ein Unterschied der mir mal aufgefallen ist:

Der String nach dem $-Zeichen wird evaluiert, weshalb beispielsweise mit $ Teilnamen möglich sind, solange sie eindeutig sind. Sicherlich ließen sich auch noch Spaltennamen finden, die als String übergeben funktionieren, aber hinter dem $-Operator R zur Verzweiflung treiben.

Code: Alles auswählen

# Funktioniert
head(mtcars[,"disp"])
head(mtcars$di)

# Funktioniert nie
head(mtcars[,"di"])
#Error in `[.data.frame`(mtcars, , "di") : undefined columns selected

mtcars[,"disp_kopie"] <- mtcars[,"disp"]
# Funktionierte zuvor, gibt jetzt NULL zurück
head(mtcars$di)

Re: fortune(312+343)

Verfasst: Do Jan 18, 2018 7:21 pm
von EDi
Ein Nachteil ist, dass man $ keine variable übergeben kann (oder zumindest nur unschön via `$`(df , Var)), weshalb ich $ nur im interaktiven Modus verwende, aber nicht in Funktionen.

Das schon erwähnte partial matching kann einem auch ordentlich in den Rücken schießen (z. b. x$a, wenn a nicht existiert, aber abc was man aber gar nicht haben will).

Re: fortune(312+343)

Verfasst: Do Jan 18, 2018 8:06 pm
von student
Was es nicht alles gibt (oder ich habe keine Phantasie)! partial matching in diesem Zusammenhang! :o Auf diese Idee wäre ich nicht gekommen, dazu bin ich wahrscheinlich zu ordentlich!

Re: fortune(312+343)

Verfasst: Do Jan 18, 2018 9:07 pm
von EDi
dazu bin ich wahrscheinlich zu ordentlich
Passiert dir auch idR nicht beim interaktiven arbeiten. Innerhalb von Funktionen kann das aber schon (unbemerkt) passieren.

Re: fortune(312+343)

Verfasst: Sa Jan 20, 2018 8:37 pm
von bigben
Hallo!

partial matching hätte ich an dieser Stelle auch nie erwartet. Das ist tatsächlich dämlich!

Ansonsten bin ich auf folgendes gekommen. Nehmen wir folgende Daten:

Code: Alles auswählen

d.f <- data.frame(1:10, 2:11)
names(d.f) <- c("A", "A-1")
str(d.f)
Meines Erachtens sollte R es nicht zulassen, dass eine Spalte 'A-1' heißt, tut es aber.

Code: Alles auswählen

> str(d.f)
'data.frame':	10 obs. of  2 variables:
 $ A  : int  1 2 3 4 5 6 7 8 9 10
 $ A-1: int  2 3 4 5 6 7 8 9 10 11
Sowas ist mir selbst schon mal passiert :? An der Stelle lohnt sich jetzt die Frage: Was ist der Wert des folgenden Ausdrucks?

Code: Alles auswählen

d.f$A-1
Ist es d.f$`A` minus 1 oder ist es d.f$`A-1` :?:

Ich wusste es nicht und habe es ausprobieren müssen. Das ist tatsächlich eine Ungewissheit, die mit `[` nicht aufgetreten wäre. Ich bin froh, dass Ihr mich jetzt vor dem partial matching gewarnt habt und werde `$` vorerst weiter regelhaft verwenden. Stattdessen passe ich lieber weiter auf, dass ich keine komischen Spaltennamen vergebe.

LG,
Bernhard

Re: fortune(312+343)

Verfasst: So Jan 21, 2018 10:06 am
von student
Hallo Bernhard,

das
names(d.f) <- c("A", "A-1")
ein schönes Beispiel! Die Datenvorbereitung ist ein zeitaufwändiger und notwendiger Schritt und in diesem Schritt bereinige ich immer zweifelhafte Variablennamen. Aus "A-1" machen ich z. B. "A_1".