If `[` is a function for subsetting in R, what is `]`? - r

I'm reading the advanced R introduction by Hadley Wickham, where he states that [ (and +, -, {, etc) are functions, so that [ can be used in this manner
> x <- list(1:3, 4:9, 10:12)
> sapply(x, "[", 2)
[1] 2 5 11
Which is perfectly fine and understandable. But if [ is the function required to subset, does ] have another use rather than a syntactical one?
I found that:
> `]`
Error: object ']' not found
so I assume there is no other use for it?

This is the fundamental difference between syntax and semantics. Semantics require that — in R — things like subsetting and if etc are functions. That’s why R defines functions `[`, `if` etc.
And then there’s syntax. And R’s syntax dictates that the syntax for if is either if (condition) expression or if (condition) expression else expression. Likewise, the syntax for subsetting in R is obj[args…]. That is, ] is simply a syntactic element and it has no semantic equivalent, no corresponding function (same as else).
To make this perhaps even clearer:
[ and ] are syntactic elements in R that delimit a subsetting expression.
By contrast, `[` (note the backticks!) is a function that implements the subsetting operation.

Somehow though, I was expecting ] to be a syntactical element, by default: indexing from the end. So I define it myself in my code:
"]" <- function(x,y) if (y <= length(x)) x[length(x)+1-y] else NA
With the given example, then:
sapply(x, "]", 1)
[1] 3 9 12
sapply(x, "]", 2)
[1] 2 8 11

Related

Create Function with special character R

I would like to create a function with the percentage sign in r. Something similar to the pipe operator in magrittr ($>$).
Here the code
%|%(x) <- function(x){...}
Unfortunately I received the following error:
Error: unexpected SPECIAL in "%|%"
Is there anything I am missing?
Thank you for your help
Syntactically invalid names need to be wrapped in backticks (`…`) to be used in code. This includes operators when using them as regular R names rather than infix operators. This is the case when you want to define them:
`%|%` <- function(a, b) a + b
It’s also the case when you want to pass them into a higher-order function such as sapply:
sapply(1 : 5, `-`)
# [1] -1 -2 -3 -4 -5
(Of course this particular example is pretty useless since most operators are vectorised so you could just write - (1 : 5) instead of the above.)
You might also see code that uses quotes instead of backticks but this is discouraged.

How to "rollback" after doing `+` = `-`?

Main Question
I did
> `+` = `-`
> 5 + 2
[1] 3
How can I "rollback" without restarting the console? Doing
> `+` = sum
of course, restores one function of + but not all. For example
> c(3,4) + c(1,2)
[1] 10
How could I restore other functions of +?
Extra related questions
Is there a name for this "kind of assignment" or the kind of functions that "+" and "-" represent?
What terms can be used to differentiate the function "+" from the function "%+%" that one could create doing
`%+%` = function(x,y){print(paste(x,"+",y,"=",x+y))}
rm() removes an object from your workspace.
rm(`+`)
will remove your custom definition that masks the built-in function.
There is nothing special about the assignment you did. As nrussell points out, infix operators (aka binary operators) are generally possible to define by wrapping them in percent signs. The basic math ones (+, -, *, /, ^, even = and <- and logical operators, ==, |, ||, &, &&, <, etc.) are special in that the parser knows they're binary operators even without being wrapped in %. You can see ?Arithmetic (alias ?"+") and ?base::Ops for more details.
You can override this by fully qualifying the function in reassignment:
`+` = `-`
5 + 2
#[1] 3
`+` <- base::`+`
5 + 2
#[1] 7
It's probably better to just rm the new function though, as Gregor suggests, otherwise you will just have extra object floating around your environment needlessly.
Functions such as +, -, *, etc., and even %+% are called infix operators. The difference is that the former are built into the R language (they are primitives), and therefore do not need to be wrapped in % % to avoid generating a parsing error.

The function of parentheses (round brackets) in R

How does R interpret parentheses? Like most other programming languages these are built-in operators, and I normally use them without thinking.
However, I came across this example. Let's say we have a data.table in R, and I would like to apply a function on it's columns. Then I might write:
dt <- data.table(my_data)
important_cols <- c("col1", "col2", "col5")
dt[, (important_cols) := lapply(.SD, my_func), .SDcols = important_cols]
Obviously I can't neglect the parentheses:
dt[, important_cols := lapply(.SD, my_func), .SDcols = important_cols]
as that would introduce a new object called important_cols to my data.table, instead of modifying my existing columns in place.
My question is, why does putting ( ) around the vector "expand" it?
This question can probably better phrased and titled. But then I would have probably found the answer by Googling if I knew the terminology to employ while asking it, hence I'm here.
While we're on that topic, if someone could point out the differences between [ ], { }, etc., and how they should be used, that would be appreciated too :)
A special feature of R (compared to e.g. C++) is that the various parentheses are actually functions. What this means is that (a) and a are different expressions. The second is just a, while the first is the function ( called with an argument a. Here are a few expressions trees for you to compare:
as.list(substitute( a ))
#[[1]]
#a
as.list(substitute( (a) ))
#[[1]]
#`(`
#
#[[2]]
#a
as.list(substitute( sqrt(a) ))
#[[1]]
#sqrt
#
#[[2]]
#a
Notice how similar the last trees are - in one the function is sqrt, in the other it's "(". In most places in R, the "(" function doesn't do anything, it just returns the same expression, but in the particular case of data.table, it is "overridden" (in quotes because that's not exactly how it's done, but in spirit it is) to do a variety of useful operations.
And here's one more demo to hopefully cement the point:
`(` = function(x) x*x
2
#[1] 2
(2)
#[1] 4
((2))
#[1] 16

Why is := allowed as an infix operator?

I have come across the popular data.table package and one thing in particular intrigued me. It has an in-place assignment operator
:=
This is not defined in base R. In fact if you didn't load the data.table package, it would have raised an error if you had tried to used it (e.g., a := 2) with the message:
Error: could not find function ":="
Also, why does := work? Why does R let you define := as infix operator while every other infix function has to be surrounded by %%, e.g.
`:=` <- function(a, b) {
paste(a,b)
}
"abc" := "def"
Clearly it's not meant to be an alternative syntax to %function.name% for defining infix functions. Is data.table exploiting some parsing quirks of R? Is it a hack? Will it be "patched" in the future?
It is something that the base R parser recognizes and seems to parse as a left assign (at least in terms or order of operations and such). See the C source code for more details.
as.list(parse(text="a:=3")[[1]])
# [[1]]
# `:=`
#
# [[2]]
# a
#
# [[3]]
# [1] 3
As far as I can tell it's undocumented (as far as base R is concerned). But it is a function/operator you can change the behavior of
`:=`<-function(a,b) {a+b}
3 := 7
# [1] 10
As you can see there really isn't anything special about the ":" part itself. It just happens to be the start of a compound token.
It's not just a colon operator but rather := is a single operator formed by the colon and equal sign (just as the combination of "<" and "-" forms the assignment operator in base R). The := operator is an infix function that is defined to be part of the evaluation of the "j" argument inside the [.data.table function. It creates or assigns a value to a column designated by its LHS argument using the result of evaluating its RHS.

What do the %op% operators in mean? For example "%in%"?

I tried to do this simple search but couldn't find anything on the percent (%) symbol in R.
What does %in% mean in the following code?
time(x) %in% time(y) where x and y are matrices.
How do I look up help on %in% and similar functions that follow the %stuff% pattern, as I cannot locate the help file?
Related questions:
What does eg %+% do? in R
The R %*% operator
What does %*% mean in R
What does %||% do in R?
What does %>% mean in R
I didn't think GSee's or Sathish's answers went far enough because "%" does have meaning all by itself and not just in the context of the %in% operator. It is the mechanism for defining new infix operators by users. It is a much more general issue than the virtues of the %in% infix operator or its more general prefix ancestor match. It could be as simple as making a pairwise "s"(um) operator:
`%s%` <- function(x,y) x + y
Or it could be more interesting, say making a second derivative operator:
`%DD%` <- function(expr, nam="x") { D(D( bquote(.(expr)), nam), nam) }
expression(x^4) %DD% "x"
# 4 * (3 * x^2)
The %-character also has importance in the parsing of Date, date-time, and C-type format functions like strptime, formatC and sprintf.
Since that was originally written we have seen the emergence of the magrittr package with the dplyr elaboration that demonstrates yet another use for %-flanked operators.
So the most general answer is that % symbols are handled specially by the R parser. Since the parser is used to process plotmath expressions, you will also see extensive options for graphics annotations at the ?plotmath help page.
%op% denotes an infix binary operator. There are several built-in operators using %, and you can also create your own.
(A single % sign isn't a keyword in R. You can see a list of keywords on the ?Reserved help page.)
How do I get help on binary operators?
As with anything that isn't a standard variable name, you have to to enclose the term in quotes or backquotes.
?"%in%"
?`%in%`
Credit: GSee's answer.
What does %in% do?
As described on the ?`%in%` help page (which is actually the ?match help page since %in% is really only an infix version of match.),
[%in%] returns a logical vector indicating if there is a match or not for its left operand
It is most commonly used with categorical variables, though it can be used with numbers as well.
c("a", "A") %in% letters
## [1] TRUE FALSE
1:4 %in% c(2, 3, 5, 7, 11)
## [1] FALSE TRUE TRUE FALSE
Credit: GSee's answer, Ari's answer, Sathish's answer.
How do I create my own infix binary operators?
These are functions, and can be defined in the same way as any other function, with a couple of restrictions.
It's a binary opertor, so the function must take exactly two arguments.
Since the name is non-standard, it must be written with quotes or backquotes.
For example, this defines a matrix power operator.
`%^%` <- function(x, y) matrixcalc::matrix.power(x, y)
matrix(1:4, 2) %^% 3
Credit: BondedDust's answer, Ari's answer.
What other % operators are there?
In base R:
%/% and %% perform integer division and modular division respectively, and are described on the ?Arithmetic help page.
%o% gives the outer product of arrays.
%*% performs matrix multiplication.
%x% performs the Kronecker product of arrays.
In ggplot2:
%+% replaces the data frame in a ggplot.
%+replace% modifies theme elements in a ggplot.
%inside% (internal) checks for values in a range.
%||% (internal) provides a default value in case of NULL values. This function also appears internally in devtools, reshape2, roxygen2 and knitr. (In knitr it is called %n%.)
In magrittr:
%>% pipes the left-hand side into an expression on the right-hand side.
%<>% pipes the left-hand side into an expression on the right-hand side, and then assigns the result back into the left-hand side object.
%T>% pipes the left-hand side into an expression on the right-hand side, which it uses only for its side effects, returning the left-hand side.
%,% builds a functional sequence.
%$% exposes columns of a data.frame or members of a list.
In data.table:
%between% checks for values in a range.
%chin% is like %in%, optimised for character vectors.
%like% checks for regular expression matches.
In Hmisc:
%nin% returns the opposite of %in%.
In devtools:
%:::% (internal) gets a variable from a namespace passed as a string.
In sp:
%over% performs a spatial join (e.g., which polygon corresponds to some points?)
In rebus:
%R% concatenates elements of a regex object.
More generally, you can find all the operators in all the packages installed on your machine using:
library(magrittr)
ip <- installed.packages() %>% rownames
(ops <- setNames(ip, ip) %>%
lapply(
function(pkg)
{
rdx_file <- system.file("R", paste0(pkg, ".rdx"), package = pkg)
if(file.exists(rdx_file))
{
rdx <- readRDS(rdx_file)
fn_names <- names(rdx$variables)
fn_names[grepl("^%", fn_names)]
}
}
) %>%
unlist
)
Put quotes around it to find the help page. Either of these work
> help("%in%")
> ?"%in%"
Once you get to the help page, you'll see that
‘%in%’ is currently defined as
‘"%in%" <- function(x, table) match(x, table, nomatch = 0) > 0’
Since time is a generic, I don't know what time(X2) returns without knowing what X2 is. But, %in% tells you which items from the left hand side are also in the right hand side.
> c(1:5) %in% c(3:8)
[1] FALSE FALSE TRUE TRUE TRUE
See also, intersect
> intersect(c(1:5), c(3:8))
[1] 3 4 5
More generally, %foo% is the syntax for a binary operator. Binary operators in R are really just functions in disguise, and take two arguments (the one before and the one after the operator become the first two arguments of the function).
For example:
> `%in%`(1:5,4:6)
[1] FALSE FALSE FALSE TRUE TRUE
While %in% is defined in base R, you can also define your own binary function:
`%hi%` <- function(x,y) cat(x,y,"\n")
> "oh" %hi% "my"
oh my
%in% is an operator used to find and subset multiple occurrences of the same name or value in a matrix or data frame.
For example 1: subsetting with the same name
set.seed(133)
x <- runif(5)
names(x) <- letters[1:5]
x[c("a", "d")]
# a d
# 0.5360112 0.4231022
Now you change the name of "d" to "a"
names(x)[4] <- "a"
If you try to extract the similar names and its values using the previous subscript, it will not work. Notice the result, it does not have the elements of [1] and [4].
x[c("a", "a")]
# a a
# 0.5360112 0.5360112
So, you can extract the two "a"s from different position in a variable by using %in% binary operator.
names(x) %in% "a"
# [1] TRUE FALSE FALSE TRUE FALSE
#assign it to a variable called "vec"
vec <- names(x) %in% "a"
#extract the values of two "a"s
x[vec]
# a a
# 0.5360112 0.4231022
Example 2: Subsetting multiple values from a column
Refer this site for an example

Resources