Latex and variables in plot label in R? - r

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.

Related

R: What exactly does \ mean in R? [duplicate]

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.

Why quote function names

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) {...}.

How does R ggplot2 get the column names via aes?

I understand how to use aes, but I don't understand the programmatic paradigm.
When I use ggplot, assuming I have a data.frame with column names "animal" and "weight", I can do the following.
ggplot(df, aes(x=weight)) + facet_grid(~animal) + geom_histogram()
What I don't understand is that weight and animal are not supposed to be strings, they are just typed out as is. How is it I can do that? It should be something like this instead:
ggplot(df, aes(x='weight')) + facet_grid('~animal') + geom_histogram()
I don't "declare" weight or animal as vectors anywhere? This seems to be... really unusual? Is this like a macro or something where it gets aes "whole," looks into df for its column names, and then fills in the gaps where it sees those variable names in aes?
I guess what I would like is to see some similar function in R which can take variables which are not declared in the scope, and the name of this feature, so I can read further and maybe implement my own similar functions.
In R this is called non-standard evaluation. There is a chapter on non-standard evaluation in R in the Advanced R book available free online. Basically R can look at the the call stack to see the symbol that was passed to the function rather than just the value that symbol points to. It's used a lot in base R. And it's used in a slightly different way in the tidyverse which has a formal class called a quosure to make this stuff easier to work with.
These methods are great for interactive programming. They save keystrokes and clutter, but if you make functions that are too dependent on that function, they become difficult to script or include in other functions.
The formula syntax (the one with the ~) probably the safest and more programatic way to work with symbols. It captures symbols that can be later evaluated in the context of a data.frame with functions like model.frame(). And there are build in functions to help manipulate formulas like update() and reformulate.
And since you were explicitly interested in the aes() call, you can get the source code for any function in R just by typing it's name without the quotes. With ggplot2_2.2.1, the function looks like this
aes
# function (x, y, ...)
# {
# aes <- structure(as.list(match.call()[-1]), class = "uneval")
# rename_aes(aes)
# }
# <environment: namespace:ggplot2>
The newest version of ggplot uses different rlang methods to be more consistent with other tidyverse libraries so it looks a bit different.

Why is it not possible to assign contrasts using with() or transform() in R?

I've been trying to learn more about environments in R. Through reading, it seemed that I should be able to use functions like with() and transform() to modify variables in a data.frame as if I was operating within that object's environment. So, I thought the following might work:
X <- expand.grid(
Cond=c("baseline","perceptual","semantic"),
Age=c("child","adult"),
Gender=c("male","female")
)
Z <- transform(X,
contrasts(Cond) <- cbind(c(1,0,-1)/2, c(1,-2,1))/4,
contrasts(Age) <- cbind(c(-1,1)/2),
contrasts(Gender) <- cbind(c(-1,1)/2)
)
str(Z)
contrasts(Z$Cond)
But it does not. I was hoping someone could explain why. Of course, I understand that contrasts(X$Cond) <- ... would work, but I'm curious about why this does not.
In fact, this does not work either [EDIT: false, this does work. I tried this quickly before posting originally and did something wrong]:
attach(X)
contrasts(Cond) <- cbind(c(1,0,-1)/2, c(1,-2,1))/4
contrasts(Age) <- cbind(c(-1,1)/2)
contrasts(Gender) <- cbind(c(-1,1)/2)
detach(X)
I apologize if this is a "RTFM" sort of thing... it's not that I haven't looked. I just don't understand. Thank you!
[EDIT: Thank you joran---within() instead of with() or transform() does the trick! The following syntax worked.]
Z <- within(X, {
contrasts(Cond) <- ...
contrasts(Age) <- ...
contrasts(Gender) <- ...
}
)
transform is definitely the wrong tool, I think. And you don't want with, you probably want within, in order to return the entire object:
X <- within(X,{contrasts(Cond) <- cbind(c(1,0,-1)/2, c(1,-2,1))/4
contrasts(Age) <- cbind(c(-1,1)/2)
contrasts(Gender) <- cbind(c(-1,1)/2)})
The only tricky part here is to remember the curly braces to enclose multiple lines in a single expression.
Your last example, using attach, works just fine for me.
transform is only set up to evaluate expressions of the form tag = value, and because of the way it evaluates those expressions, it isn't really set up to modify attributes of a column. It is more intended for direct modifications to the columns themselves. (Scaling, taking the log, etc.)
The difference between with and within is nicely summed up by the Value section of ?within:
Value For with, the value of the evaluated expr. For within, the modified object.
So with only returns the result of the expression. within is for modifying an object and returning the whole thing.
While I agree with #Jornan that within is the best strategy here, I will point out it is possible to use transform you just need to do so in a different way
Z <- transform(X,
Cond = `contrasts<-`(Cond, value=cbind(c(1,0,-1)/2, c(1,-2,1))/4),
Age = `contrasts<-`(Age, value=cbind(c(-1,1)/2)),
Gender= `contrasts<-`(Gender, value=cbind(c(-1,1)/2))
)
Here we are explicitly calling the magic function that is used when you run contrasts(a)=b. This actually returns a value that can be used with the a=b format that transform expects. And of course it leaves X unchanged.
The within solution looks much cleaner of course.

Used normal text in combination with normal text in plot

UPDATE: I actually found the solution myself, see below.
In R I want to add a label to a plot containing both subscript and normal text. To be more precise, I would like to use mtext() (or any other method that does the trick) to add a text below a plot. The text should look like this:
This can easily done in latex with $B\pm t_{a/2}SE(B)$
In R I come as far as mtext(expression(B%+-%t[a/2])), which does print
But the difficulty is in geting the SE(B) part after it, because of expression treating SE(B) as a function. I've tried several combinations with paste, but to no avail. I'm sure there must be a simple solution to this, but I wasn't able to find one after quite a long search.
UPDATE:
Wow, found the solution myself. As I said I have tried combinations of expression and paste and was sure I tried this before, but apparently, I did not. The solution is this:
mtext(expression(paste(B%+-%t[a/2],"SE(B)")))
I see you have solved this, but your final solution is much more nicely and succinctly handled by dropping the use of paste() and using the ~ operator to add spacing:
expression(B %+-% t[a/2] ~ SE(B))
e.g.:
plot(1:10, xlab = expression(B %+-% t[a/2] ~ SE(B)))
which gives
You can add extra spacing by using multiple ~: ~~~ for example. If you just want to juxtapose two parts of an equation, using the * operator, as in:
plot(1:10, xlab = expression(B %+-% t[a/2] * SE(B)))
which gives:
It isn't immediately clear from your Q which one is preferable.

Resources