I tried `$`(mtcars,cyl,drop=FALSE), but this threw an error. I know that in practice you would use [ or [[ instead, but I'm curious, can drop=FALSE be passed to $?
The $ function doesn't have a drop= parameter. While they are used for similar things, the $ function is distinct from the [ function which does have a drop= parameter.
I'm assuming that you are only interested in the case for using $ with data.frames, but there's actually no special data.frame method for $, it just treats the data.frame like a list. And drop= wouldn't make as much sense in the case of a generic list.
Related
The codes are as follows
l1<-list(1,2)
names(l1)<-c("a","b")
l1$"b"
a<-"b"
l1$a
The output for l1$"b" is 2,but for l1$a is 1.
This is not consistent.I don't know why and how to deal with it.
I hope you can help me!
Thank you!
You can use this functional notation
a<-"b"
`[[`(l1 , a)
#> 2
To directly respond to your question about why this is the case: unlike the [ and [[ operators, the $ operator does not allow computed indices, i.e. The name used to index into x as in x$name must be a literal character string or symbol.
So, the semantics of l1$a is something like:
get(quote(a), envir = as.environment(l1), inherits = FALSE)
# Lightly modified from ?`$` for clarity
As langtang and Mohamed have noted above, you can use the [ or [[ operators instead which do allow computed indices.
Quick question:
How can I access a variable directly out of a dataframes list?
I tried
df_list[i]$variable which is not working.
or df_list[(i)]$variable...
or df_list[i[1]]
is there a way?
You may use [[ to access the dataframe inside the list. I am assuming you are running in a for loop. To access the variable you may use df_list[[i]]$variable.
You may also read The difference between bracket [ ] and double bracket [[ ]] for accessing the elements of a list or dataframe
I believe the following to be true of the $ operator:
It allows names to be partially matched. For example, data$Sky can match data$Skywalker if there is no Sky name in use.
It cannot be used for atomic vectors, unlike [ and [[.
It cannot be combine with operators like -. There is no valid syntax like mtcars$-mpg. [ and [[ cannot do this with names either, but mtcars[,-1] works.
It is for names only.
Partial matching aside, for a data frame, data$name is equivalent to data[,"name"] e.g. mtcars$cyl is the same as mtcars[,"cyl"]. I'm pretty sure that data[["name"]] is also equivalent, e.g. mtcars[["cyl"]].
Partial matching aside, for a named list that is not a data frame, data$name is the same as data[["name"]].
Does this mean that if I don't care about partial matching, I can always replace $ with [ or [[? Or is there some functionality that I've missed?
For base R, my best guess comes from the documentation for $. The following quotes are the most relevant:
$ is only valid for recursive objects
$ does not allow computed indices, whereas [[ does. x$name is equivalent to x[["name", exact = FALSE]]. Also, the partial matching behavior of [[ can be controlled using the exact argument.
the default behaviour is to use partial matching only when extracting from recursive objects (except environments) by $. Even in that case, warnings can be switched on by options(warnPartialMatchDollar = TRUE).
So it seems that the documentation confirms my belief that, aside from partial matching, $ is just syntactic sugar. However, there are four points where I am unsure:
I never put too much faith in R's documentation. Because of this, I'm sure that an experienced user will be able to find a hole in what I've said.
I say that this is only my guess for base R because $ is a generic operator and can therefore have its meaning changed by packages, tibbles being a common example.
$ and [ can also be used for environments, but I have never seen anyone do so.
I don't know what "computed indices" are.
According to a book on advanced R, the $ and the [ operator are the same on dataframes (not on lists) except from the partial matching. It states
$ is a shorthand operator: x$y is roughly equivalent to x[["y"]].
...The one important difference between $ and [[ is that $ does
(left-to-right) partial matching:
Here is the quote: Section 4.3.2 of the next link:
https://adv-r.hadley.nz/subsetting.html#section-1
I have noticed this unexpected feature:
foo <- list(whatever=1:10)
Now, the following works as well:
foo$wha
foo$w
foo$whateve
However, the following does not:
foo[["wha"]]
This has the unexpected consequences (unexpected for me, that is) that if you have two potential names, like "CXCL1" and "CXCL11", and you want to know whether CXCL1 is not null by inspecting !is.null(foo$CXCL1), it will return TRUE even if CXCL1 null, but CXCL11 isn't.
My questions are:
How does that work?
What is the difference between foo$whatever and foo[["whatever"]]?
Why would anyone want this behavior and how do I disable it?
Partial matching only works with unique initial subsequences of list names. So, for example:
> l <- list(score=1, scotch=2)
> l$core #only INITIAL subsequences
NULL
> l$sco #only UNIQUE subsequences
NULL
> l$scor
[1] 1
Both [[ and $ select a single element of the list. The main differences are that $ does not allow computed indices, whereas [[ does, and that partial matching is allowed by default with operator $ but not with [[.
These Extract or Replacement operators come from S, although R restricts the use of partial matching, while S uses partial matching in most operators by default.
In your example, if CXCL1 and CXCL11 coexist and you index foo$CXCL1, that's not a partial match and should return CXCL1's value. If not, maybe there's another problem.
I should point out, [[ not allowing partial matching as default starts from version R 2.7.0 onwards.
I am very new to R and trying to figure out how to use indexing with $. If I wanted to add an argument, say drop(), how do I use $ with arguments? I tried:
subset <- mydata_df$variable1[drop=FALSE]
This doesn't seem to work.
If you look at the ?"[.data.frame" help page, you'll see that the $ operator is distinct from the [ operator and only the latter has the drop= argument. Thus the correct syntax for such an extraction is
mydata_df[, "variable1", drop=FALSE]