I’m required to use/learn R for a new lecture at uni and I’m currently struggling a bit with its syntax. I want to plot (via curve) a simple function, but I can’t seem to get it working with an inline lambda-like function.
I’ve tried the following:
> curve( function(x) x^2 )
Error in curve(function(x) x^2) :
'expr' did not evaluate to an object of length 'n'
When I however store the function in a variable first, it works:
> quad <- function(x) x^2
> curve( quad )
Is such an inline use not allowed in R? Is there any other way to make this work without defining an extra function? Thanks!
Just for completeness. You can use "lambda-like" (anonymous) functions in R but if you want to put them to immediate use, you need to enclose the function definition in parentheses or curly braces:
(function (x) x+1) (1)
{function (x,y) x^y} (2,3)
In the case of curve the first argument is either expression or a function name - but if it is a function name then it is first converted to an expression. (See first few lines in the source code of curve). So if its' not a function name, you'll need an expression – which may contain a "lambda" function:
curve((function (x) x^2)(x))
If you want to use a function (as opposed to its name) as the argument, you can use plot.function:
plot(function(x) x^2)
From R 4.1 on, you can use \(x) lambda-like shorthand:
R now provides a shorthand notation for creating anonymous functions,
e.g. \(x) x + 1 is parsed as function(x) x + 1.
With function(x) x^2:
(\(x) x^2)(2)
#[1] 4
This can be used with curve :
curve((\(x) x^2)(x))
But as stated in comments, in this case an expression is more straightforward :
curve(x^2)
You have to look at the source of curve to appreciate what is happening (just type curve at the prompt and press enter).
There you can find how the expression passed is parsed.
The only way a function is discovered as being just that, is when only its name is passed along (see the is.namepart). If that is not the case, the expression is called for every x. In your case: for every x, the result is a function, which is not a happy thought for plotting...
So in short: no you cannot do what you tried, but as #ROLO indicated, you can immediately pass the function body, which will be parsed as an expression (and should contain x). If this holds multiple statements, just enclose them in curly braces.
Related
What is the reason behind quoting the name of your function? I have seen this in a couple of packages (for example line number 2 here in the quantmod package). Instead of writing
f <- function(x)
they write
"f" <- function(x)
Another example is from the gratia (line 88) package where functions are back quoted:
`f` <- function(x)
Transferred from Allan Cameron's comment.
It doesn't make any difference for the functions in the link you shared. It appears to be more of a stylistic choice from the developer to allow the top of function declarations to stand out. Sometimes it is necessary to wrap function names in quotes if they contain illegal characters.
The most frequently seen ones in R are the [<- type operators. That is, if you want to define a function that writes to a subset of a custom class so the user can do x[y] <- z then you need to write a function like "[<-.myclass" <- function(y, z) {...}.
I've tried finding this on SO without any luck:
How do I convert a closure object into a string in R?
I have a list of functions, like this:
functions = c(function(x) 2*x, function(x) sin(x*pi), function(x))
And, I iterate over them like for (func in functions){..., and I'd like to be able print the function expression as part of my plotting.
I've tried:
toString(eval(func))
as.character(eval(func))
What gives?
Related links:
How to evaluate a variable as an expression for axis label in R?
Evaluate expression given as a string
There seems to be no easy way to accomplish this. Here is the best way I found:
as.character(parse(text=as.list(func)))
For a more general solution, you can capture the output, as #chinsoon said.
My question might sound stupid but I have noticed that . and % is often used in R and to be frank I don't really know why it is used.
I have seen it in dplyr (go here for an example) and data.table (i.e. .SD) but I am sure it must be used in other place as well.
Therefore, my question is:
What does . mean? Is it some kind of R coding best practice nomenclature? (i.e. _functionName is often used in javascript to indicate it is a private function). If yes, what's the rule?
Same question for %, which is also often used in R (i.e. %in%,%>%,...).
My guess always has been that . and % are a convenient way to quickly call function but the way data.table uses . does not follow this logic, which confuses me.
. has no inherent/magical meaning in R. It's just another character that you can use in symbol names. But because it is so convenient to type, it has been given special meaning by certain functions and conventions in R. Here are just a few
. is used look up S3 generic method implementations. For example, if you call a generic function like plot with an object of class lm as the first parameter, then it will look for a function named plot.lm and, if found, call that.
often . in formulas means "all other variables", for example lm(y~., data=dd) will regress y on all the other variables in the data.frame dd.
libraries like dplyr use it as a special variable name to indicate the current data.frame for methods like do(). They could just as easily have chosen to use the variable name X instead
functions like bquote use .() as a special function to escape variables in expressions
variables that start with a period are considered "hidden" and will not show up with ls() unless you call ls(all.names=TRUE) (similar to the UNIX file system behavior)
However, you can also just define a variable named my.awesome.variable<-42 and it will work just like any other variable.
A % by itself doesn't mean anything special, but R allows you to define your own infix operators in the form %<something>% using two percent signs. If you define
`%myfun%` <- function(a,b) {
a*3-b*2
}
you can call it like
5 %myfun% 2
# [1] 11
MrFlick's answer doesn't cover the usage of . in data.table;
In data.table, . is (essentially) an alias for list, so any* call to [.data.table that accepts a list can also be passed an object wrapped in .().
So the following are equivalent:
DT[ , .(x, y)]
DT[ , list(x, y)]
*well, not quite. any use in the j argument, yes; elsewhere is a work in progress, see here.
I'm having trouble applying a custom function in R. The basic setup is I have a bunch of points, I want to drop a grid over top and get the max z value from each cell.
The code I'm trying is below. The results I'm looking for would return myGrid$z=c(5,10,na). The na could be a different value as well as long as I could filter it out later. I'm getting an error at the apply stage
I believe there is an error in how I'm using apply, but I just haven't been able to get my head wrapped around apply.
thanks,
Gordon
myPoints<-data.frame(x=c(0.7,0.9,2),y=c(0.5,0.7,3), z=c(5,3,10))
myGrid<-data.frame(x=c(0.5,2,4),y=c(0.5,3,10))
grid_spacing = 1
get_max_z<-function(x,y) {
z<-max(myPoints$z[myPoints$x > (x-grid_spacing/2)
& myPoints$x <= (x+grid_spacing/2)
& myPoints$y > (y-grid_spacing/2)
& myPoints$y <= (y+grid_spacing/2)])
return(z)
}
myGrid$z<-apply(myGrid,1,get_max_z(x,y),x=myGrid$x,y=myGrid$y)
Edited to include the return(z) line I left out. added $y to line of custom function above return.
First of all I would recommend you to always boil down a question to its core instead of just posting code. But I think I know what your problem is:
> df <- data.frame(x = c(1,2,3), y = c(2,1,5))
> f <- function(x,y) {x+y}
> apply(df,1,function(d)f(d["x"],d["y"]))
[1] 3 3 8
apply(df,1,.) will traverse df row wise and hand the current row as an argument to the provided function. This row is a vector and passed into the anonymous function via the only available argument d. Now you can access the elements of the vector and hand them further down to your custom function f taking two parameters.
I think if you get this small piece of code then you know how to adjust in your case.
UPDATE:
Essentially you make two mistakes:
you hand a function call instead of a function to apply.
function call: get_max_z(x,y)
function: function(x,y)get_max_z(x,y)
you misinterpreted the meaning of "..." in the manual to apply as the way to hand over the arguments. But actually this is just the way to pass additional arguments independent of the traversed data object.
How do I use variables in Latex expressions in R?
For example:
plot(X, Y, main=expression(R^2))
Will put R with a nice superscripted 2 as main title.
But let's say I want it to say 'R^2: 0.5', with 0.5 coming from a R variable. How do I do that?
The hack of Owen is pretty cool, but not really the common way to do that. If you use bquote, this is actually pretty easy. bquote will do the same as quote, with the exception that everything between .() will be evaluated in a specified environment (or the global, if nothing is specified).
A trivial example :
X <- 1:10
Y <- 1:10
a <- 0.8
plot(X,Y,main=bquote(R^2 : .(a)))
Gives :
See also ?bquote and ?plotmath for more examples and possibilities
Well this works...
call(':', quote(R^2), a)
though it feels a little hacky to me since it's using R's : operator, whereas you just want to stick some text on the end. Maybe there's a better way?
tikz and psfrag allow you to use actual LaTeX code and output instead of plotmath's, resulting in better typographic consistency.
See this question for details. Getting LaTeX into R Plots
Another variation on #Joris' theme is substitute(). You give substitute() an expression and an environment or list within which to evaluate the expression. Passing a list is usually easiest, especially for jobs such as the one posed here.
plot(X,Y, main = substitute(R^2 : a, list(a = a)))
We can see why this works, by looking solely at the substitute() call:
> substitute(R^2 : a, list(a = a))
R^2:0.8
The a in the expression is replace with the value of a in the list.