Lazarus Thurston
Lazarus Thurston

Reputation: 1287

peculiar syntax for function within()

I came across this fantastic function called

within {base}

I use it more often now than the much hyped

mutate {dplyr}

My question is, why is within() having such a peculiar format with assignment operators used <- instead of the usual = for args; How is it different from mutate other than what is given in this fantastic article I found. I am interested to know the underlying mechanism. Article of Bob Munchen - 2013

Upvotes: 3

Views: 548

Answers (2)

Pop
Pop

Reputation: 12401

Args of within are not assigned with <- but with the usual =.

Let's see the first example in your link:

mydata.new <- within(mydata, {
+              x2 <- x  ^ 2
+              x3 <- x2 + 100
+              } )

Here,

{
 x2 <- x  ^ 2
 x3 <- x2 + 100
}

is just an argument of the function (an R expression). Nor x2 nor x3 are arguments to within. The function could have been called in that way instead to make it clearer:

mydata.new <- within(data = mydata, expr = {
            x2 <- x  ^ 2
            x3 <- x2 + 100
            })

Upvotes: 1

Joris Meys
Joris Meys

Reputation: 108523

The function within takes an expression as second argument. That expression is essentially a codeblock, best contained within curly brackets {}.

In this codeblock, you can assign new variables, change values and the likes. The variables can be used in the codeblock as objects.

mutate on the other hand takes a set of arguments for the mutation. These arguments have to be named after the variable that should be created, and get the value for that variable as the value.

So :

mutate(iris, ratio = Sepal.Length/Petal.Length)
# and
within(iris, {ratio = Sepal.Length/Petal.Length})

give the same result. The problem starts when you remove the curly brackets:

> within(iris, ratio = Sepal.Length/Petal.Length)
Error in eval(substitute(expr), e) : argument is missing, with no default

The curly brackets enclosed an expression (piece of code), and hence within() worked correctly. If you don't use the {}, then R semantics reads that last command as "call the function within with iris as first argument and a second argument called ratio set to Sepal.Length/Petal.Length". And as the function within() doesn't have an argument ratio, that one is ignored. Instead, within looks for the expression that should be the second argument. But it can't find that one, so that explains the error.

So there's little peculiar about it. Both functions just have different arguments. All the rest is pretty much how R deals with arguments.

Upvotes: 2

Related Questions