Indexing using $ and arguments? - r

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]

Related

Can't extract the element properly using the operator `$` in r when using the character variable

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.

Can drop=FALSE be passed to $?

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.

Aside from partial matching, can the $ operator do anything that [ and [[ cannot?

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

Using an argument to define an extraction operator in user defined function

I have created a function that uses the subset function. How do I assign an argument then have it used after the extraction operator?
Here is what I have now:
function_test<-function(time1,size,Param){
test1_in_equilibrium<-(subset(alldata,Time>=time1 & FinalPopSize==size)$Param)
}
Given the following call:
function_test(100,5000,Time)
I would like R to expand it like so:
test1_in_equilibrium<-(subset(alldata,Time>=time1 & FinalPopSize==size)$Param)
Unfortunately when I attempt to run this function I receive the error object "Time" not found.
I assume I am missing an escape character or something similar but have been unable to find it.
Thanks!
You cannot add the $ operator to a function call and you cannot use a variable with the $ operator.
However, I understand that you want to get the column defined by the input variable Param from the subsetted data.frame. In this case you can easily write the function like this:
function_test <- function(time1,size,Param){
reduced_data <- subset(alldata, Time>=time1 & FinalPopSize==size)
test1_in_equilibrium <- reduced_data[, Param]
}

how to use loop to run through set of lists

I am trying to create an r loop to run a command on a series of datasets. the command is make.design.data from the RMark library. The only argument it takes is the name of a list. I have 17 of these lists I'd like to pass to make.design.data This is the code I've been trying to use
DFNames<-c("DFAmerican.Goldfinch", "DFAmerican.Robin","DFBarn.Swallow","DFBobolink", "DFBrown.head.Cowbird", "DFCedar.Waxwing", "DFCommon.Grackle","DFCommon.Yellowthroat", "DFEuropean.Starling","DFHorned.Lark", "DFKilldeer","DFRed.wing.Blackbird", "DFSavannah.Sparrow", "DFSong.Sparrow","DFTree.Swallow", "DFVesper.Sparrow", "DFYellow.Warbler")
#in my environment each of the names given to DFNames represents a list
for (x in DFNames){
n<-make.design.data(x)
assign(paste0("ddl",x),n)
}
this gives me the error
Error in data$model : $ operator is invalid for atomic vectors
can anyone please suggest a way to fix my code, or a different way of tackling this?
Thanks, Jude
Instead, you can make a list of the actual data sets instead of a vector of their names.
x <- list(DFAmerican.Goldfinch, ...)
Then you can use:
lapply(x, make.design.data)`.
Or use get inside your for loop:
for (x in DFNames) {
make.design.data(get(x))
}
The "R" way is the former using lists and the apply family. Then you can avoid the gymnastics of assign.

Resources