0

fortune(312) and fortune(343) allude to the problems with using $ to extract elements of a list instead of [[, but aren't specific about what exactly the dangers are.

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)

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)

Looking through the documentation for `$`, I've found that

$ is only valid for recursive objects

and

The main difference is that $ does not allow computed indices, whereas [[ does [...] Also, the partial matching behavior of [[ can be controlled using the exact argument.

So, is the argument to use [[ over $ because the former offers greater control and transparency in writing code? What are the actual risks of using $, and if [[ is preferred are there any circumstances where it is appropriate to use $-extraction?

Empiromancer
  • 3,778
  • 1
  • 22
  • 53
  • 5
    sort of opinion-based, but basically I would say that partial matching is the primary danger. – Ben Bolker Feb 10 '16 at 19:54
  • 4
    `$` is fine when you know the name for sure. The problem is when people try to use `$` in dynamic code, e.g. `col = "mpg"; mtcars$col; mtcars[col]`. This is what `fortune(312)` means when it says *a column whose name is stored in y*. If the column is named `"y"`, then `x$y` is just fine, but if `y` is a variable holding a string representation of the column name, then `$` won't work and you need to use `[` or `[[`. – Gregor Thomas Feb 10 '16 at 19:56
  • `$` is intended for interactive use. Your second quote from the documentation explains the potential problems in programmatic use. That said, I've never had a serious problem with it. – Roland Feb 10 '16 at 19:56
  • 1
    Also related: [Why is `[` better than `subset`?](http://stackoverflow.com/q/9860090/903061). – Gregor Thomas Feb 10 '16 at 19:59
  • 3
    You can also search the R-Help Archives to see the contexts in which both of these fortunes originated: [fortune 312](https://stat.ethz.ch/pipermail/r-help/2012-February/303183.html), [fortune 343](https://stat.ethz.ch/pipermail/r-help//2013-March/350214.html). Both involve the situation I describe above. – Gregor Thomas Feb 10 '16 at 20:13
  • @GregSnow uses the euro – rawr Feb 10 '16 at 20:47

1 Answers1

2

Consider the list:

foo<-list(BlackCat=1,BlackDog=2, WhiteCat=3,WhiteDog=4)

Suppose you want to call the indice according to the two user parametric variables: colour and animal species. Parametrising the colour and the species somewhere in the code as

myColour<-"Black"
mySpecies<-"Dog"

you can make the call to index parametric easily as

foo[[paste0(myColour,mySpecies)]]

by using [[ or [. However, this is not case for $ extraction: foo$paste0(myColour,mySpecies) would not evaluate the function paste0.

submartingale
  • 715
  • 7
  • 16