How to include subscript in text for plot point labels - r

Hi I'm new to R so I apologise if this is a very basic question.
I'm trying to add text to a plot at point 11 on the x axis and point 900 on the y axis that will read t0= -4.0280 with the 0 as subscript. Where t0 <- -4.0280
To do this I've tried:
text(11,900,paste("t[0]=",t0),cex=0.8)
# which gives
't[0]= -4.0280'
text(11,900,expression(paste("t[0]=",t0)),cex=0.8)
# which gives
't[0]=t0'
# the closest I've gotten is:
text(11,900,expression(paste(t[0]==t0)),cex=0.8)
which will use subscript but return t0 instead of my value of -4.0280.
Could anyone show me where Ive gone wrong?
Cheers.

You can replace expression with substitute. There's no need for the paste. The argument list(t0 = t0) tells substitute to replace the string t0 with the value of the object t0:
plot(1,1)
t0 <- 1.3
text(1, 0.8, substitute(t[0]==t0, list(t0 = t0)), cex = 0.8)

Slightly shorter than substitute is with bquote:
plot(1,1)
t0 <- -4.0280
text(1, 0.8, bquote("t"[0] ~ "=" ~ .(t0)))
of if you'd like to use paste in there:
text(1, 0.8, (bquote("t"[0]~.(paste0('=',t0)))))
This kind of Q has popped up previously:
Using subscript and variable values at the same time in Axis titles in R
Concatenate strings and expressions in a plot's title

Related

evaluating piecewise function (Error in curve(..., : 'expr' did not evaluate to an object of length 'n')

I am trying to create a piecewise function using R. I am having trouble with my plot function
a <- function(x){
ifelse(( x <-1),0,ifelse((-1<x & x<2),(x^3+1)/9ifelse((x>2),1,NA)))
}
plot(a,xlim=c(-5,5), ylim = c(-4, 7), col = "red")
I am not sure if I never created my function properly or if there is something wrong with the way that I have plotted it. The piecewise function is a little confusing because it's a straight line of 1 and 0 at its intervals and from -1 to 2 it's a weird function.
There are two typos in your function; one is tricky.
(1) missing a comma before the third ifelse (this is probably a cut-and-paste error); (2) in x<(-1), you need parentheses (or at least a space) so R doesn't think you're assigning the value 1 to x (i.e. x <- 1).
a <- function(x) {
ifelse(( x <(-1)),0,ifelse((-1<x & x<2),(x^3+1)/9,
ifelse((x>2),1,NA)))
}
plot(a,xlim=c(-5,5), ylim = c(-4, 7), col = "red")

In R, why is there awkward output in the legend when I am using paste() instead of c() in addition to pretty10exp()?

I'm trying to make the legend of this plot pretty, so I need there the be an actual superscript, which is why I am using the pretty10exp() function from the sfsmisc library. It works when I use the c() function.
However, I am also trying to keep the string and the scientific notation number on the same line. The legend() is broken into two lines, which I think is due to c(). I thought I could use paste(), but for some reason the output is now incorrect.
plot(1:12)
pVal <- 4
legend("topright", legend = c("P value:", sfsmisc::pretty10exp(pVal)), cex = 1.5)
legend("topright", legend = paste("P value:", sfsmisc::pretty10exp(pVal)), cex = 1.5)
pVal being an arbitrary number represented in scientific notation. The second line results in output like this: "P value: (significand) %*% 10^-4". The first line also doesn't give me what I want. How can I fix this problem?
pretty10exp returns an expression which allows it to use the ?plotmath features for making nice looking numbers. When working with expressions, you can't just paste values in like strings. You need to manipulate them with a special set of functions. One such function is substitute. You can do
plot(1:12)
pVal <- 4
legend("topright", cex = 1.5,
legend = substitute("P value: "*x, list(x=sfsmisc::pretty10exp(pVal)[[1]])) )
We use substitute() to take the value contained in the expression from pretty10exp and prefix it with the label you want. (We use * to concatenate rather than paste() since plotmath allows it)
This is what I would do:
fun <- function(text, pVal) {
y <- floor(log10(pVal))
x <- pVal / 10^y
bquote(.(text)*":" ~ .(x) %.% 10 ^ .(y))
}
plot.new()
text(0.5,0.7,fun("P value", 0.4))
text(0.5, 0.3, fun("P value", signif(1/pi, 1)))
No package is needed.

R - Text Formatting of Plot Text that is not hard-wired

I would like to add formatted text to a plot (title, axes labels, legend, etc.). A standard solution would be e.g.
plot(1, 1, ylab=substitute(lambda[1]))
where the y-axis label will be the greek letter λ with subscript 1. That is what I want but unfortunatelly it is hard-wired. I would like it to be flexible, i.e. to have an option to pass the text as an argument of a function. So, looking at r help, I found that the argument for substitute is an expression. So I've tried
sometext <- "lambda[1]"
e <- parse(text="sometext")
plot(1, 1, ylab=substitute(e))
But substitute ignores that e is an object an simply prints the text 'e' as the label. So instead I tried
plot(1, 1, ylab=eval(e))
which was better because eval at least evaluates the expression but the label now is literally 'lambda[1]', i.e. it is not evaluated as a greek letter λ with a subscript.
I then explicitly stated that 'e' is an expression doing
e <- expression(sometext)
and running the two previous plot commands but with the same results as before.
The closest I came to what I wanted ot achieve was doing
plot(1, 1, ylab=substitute(var[i], list(var="lambda", i=1)))
where at least the 1 is printed as a subscript but the text 'lambda' instead of the greek letter λ is printed.
Any suggestions on how can I achieve what the first command does but not hard-wired? E.g. using a string and somehow converting it to the right object so that it will be displayed properly? Thanks.
Daniel
You can pass the label as an expression like so and then use substitute inside the function:
dwat <- function(expr){
plot(1, 1, ylab = substitute(expr))
}
dwat(lambda[1])
dwat(mu[2])
If you want to pass a string instead of an expression use parse:
dwat_string <- function(string){
plot(1, 1, ylab = parse(text = string))
}
dwat_string("mu[1]")
Another option would be to use the ellipsis approach. That way you can pass an xlab or any other argument to plot:
dwat2 <- function(...){
plot(1, 1, ...)
}
dwat2(ylab = expression(lambda[1]))
you were close, checks if this works
substitute(lambda[i],list(i=i))

R axis text no dots

I want to add the following x-axis label to my bar plot but unfortunately R does not recognize the character '!' and prints dots instead of whitespaces:
I want: I get:
!src x.x.x.x X.src.x.x.x.x
!TCP X.TCP
!udp && !src x.x.x.x X.udp.....src.x.x.x.x
Additionally a would like to increase the margin because the text is to long and when setting the size over 'cex.names=0.6' then it just vanishes!?
There are two reason I can think of that R will have substituted X. for instances of !.
I suspect that the labelling you are seeing is due to R's reading of your data. Those column names aren't really syntactically valid and the erroneous character has been replaced by X.. This happens at the data import stage, so I presume you didn't check how R had read your data in?, or
You have a vector and the names of that vector are similarly invalid and R has done the conversion.
However, as you haven't made this reproducible it could be anything.
To deal with case 1 above, either edit your data file to contain valid names or pass check.names = FALSE in your read.table() call used to read in the data. Although doing the latter will make it difficult for you to select variable by name without quoting the name fully.
If you have a vector, then you can reset the names again:
> vec <- 1:5
> names(vec) <- paste0("!",LETTERS[1:5])
> vec
!A !B !C !D !E
1 2 3 4 5
> barplot(vec)
Also note that barplot() has a names.arg argument that you can use to pass it the labels to draw beneath each bar. For example:
> barplot(vec, names.arg = paste0("!", letters[1:5]))
which means you don't need to rely on what R has read in/converted for you as you tell it exactly what to label the plot with.
To increase the size of the margin, there are several ways to specify the size but I find setting it in terms of number of lines most useful. You change this via graphical parameter mar, which has the defaults c(5,4,4,2) + 0.1 which correspond to the bottom, left, top, and right margins respectively. Use par() to change the defaults, for example in the code below the defaults are store in op and a much larger bottom margin specified
op <- par(mar = c(10,4,4,2) + 0.1)
barplot(vec, names.arg = paste0("!", letters[1:5]), las = 2)
par(op) ## reset
The las = 2 will rotate the bar labels 90 degrees to be perpendicular to the axis.
One option is to use ann=F and add anotation to the plot using mtext.
x <- 1:2
y <- runif(2, 0, 100)
par(mar=c(4, 4, 2, 4))
plot(x, y, type="l", xlim=c(0.5, 2.5), ylim=c(-10, 110),
axes=TRUE, ann=FALSE)
Then add annotation:
mtext("!udp && !src x.x.x.x ", side=1, line=2)
Edit It is a question of a barplot and not simple plot.
as said in Gavin solution, the names argument can be setted. Here I show an example.
barplot(VADeaths[1:2,], angle = c(45, 135),
density = 20, col = "grey",
names=c("!src x.x.x.x", "!TCP", "!udp && !src x.x.x.x", "UF"),
horiz=FALSE)

How to add nice formated anotations to a R base graph using expression and the value of a variable?

Say, I have a variable rv which has some numerical value. Now, I want to plot the value of this variable on a base plot but preceded by a nicely formatted symbol e.g., r subscript m, using expression. To write on the plot I use mtext.
However, what I get is either the value of the variable, but no nicely formatted symbol (left annotation), or a nicely formatted symbol, but not the value of the variable, but the variable name...
I tried to play around with eval, but didn't get what I wanted. Here is my code:
plot(1:10, rep(10,10), ylim=c(0,12))
rv <- 0.43
#left annotation:
mtext(paste(expression(italic(r[M])), " = ", rv), side = 1, line = -1.5, adj = 0.1)
#right annotation:
mtext(expression(paste(italic(r[M]), " = ", rv)), side = 1, line = -1.5, adj = 0.9)
This is the result:
How do i get both, nice format and value of the variable? Thanks.
btw: I know that I can get it, if I use two times mtext and play around with adj and stuff. But I would really like to get it in one call or without playing around with the position of two annotations.
The bquote function will create an expression and alow substitution of values using .(var) syntax. for your case do something like:
text( 5,1, bquote( italic(r[M]) == .(rv) ) )
Just combine what you have and plot two pieces, joined by using adj:
R> plot(1:10, rep(10,10), ylim=c(0,12))
R> text(2,12, expression(paste(italic(r[M]))), adj=1)
R> text(2,12, paste("=", rv), adj=0)

Resources