I've learned to apply bold to a portion of the text used in a plot title using mtext() expression() and paste(). This works great if you specify the strings outright. However, in the project I'm working on now, the portion of text to be bolded needs to be obtained through a call to an element of a vector. However, the characters needed in the call syntax are interpreted by expression() and the call fails.
junk <- c("I'm Special", "You're Special")
plot(0, type="n")
mtext(expression(paste("Do you think ", bold(junk[1]),"today?")),3,2)
mtext(expression(paste("I think ", bold(junk[2]), "today.")),3,1)
Any thoughts on how to approach this? I am trying to avoid specifying the bold text directly.
bquote has a decent interface for this. You just surround the variable you want to substitute with .(). You could also use substitute with expression.
junk <- c("I'm Special", "You're Special")
plot(0, type="n")
mtext(bquote(paste("Do you think ", bold(.(junk[1])),"today?")),3,2)
mtext(bquote(paste("I think ", bold(.(junk[2])), "today.")),3,1)
Related
I'm trying to create a list of labels that contain italics. I can do it with "expression" like this, and when I put them on a plot (by adding a legend as an example, but I'll use them different ways), it all works nicely.
sp.names=c(expression(paste("species ",italic("one")," sp.")),
expression(paste("species ",italic("two")," sp.")))
plot(1:10)
legend("topleft",legend=sp.names)
But instead of specifying the words in the label directly in the code, I want to call them from cells in a dataframe (because there are a lot of them and they change depending on my underlying data). But when I try and specify which dataframe cell I want, it doesn't print the labels correctly (see below). Perhaps there is a different way for me to call the cell that I want that the "expression" function will recognise?
df=data.frame(V1=c("species","species","species"),V2=c("one","two","three"))
sp.names=c(expression(paste(df$V1[1],italic(df$V2[1])," sp.")),
expression(paste(df$V1[2],italic(df$V2[2])," sp.")))
plot(1:10)
legend("topleft",legend=sp.names)
Use substitute, it substitutes variables in expressions.
sp.names=c(substitute(V1 ~ italic(V2) ~ "sp.", df[1,]),
substitute(V1 ~ italic(V2) ~ "sp.", df[2,]))
I also removed the unneeded paste (which has a different meaning within plotmath) and replaced it with ~ for increased readability.
Give bquote a shot.
sp.names <- c(bquote(.(df$V1[1])~italic(.(df$V2[1]))~" sp."),
bquote(.(df$V1[2])~italic(.(df$V2[2]))~" sp."))
plot(1:10)
legend("topleft", legend=sp.names)
Specifying text in a base R plot() with formatting such as italics / bold font / newline usually involves one or more of the following functions:
paste()
expression()
atop()
substitute()
italic()
Is there an intuitive explanation for the differences between these functions and when best to apply them?
What you're referring to is the plotmath syntax.
To start off, let's make it clear that for a plotmath expression to be interpreted as such, you tell R it's an "expression" and that is why you need expression().
So any time you want to use special symbols or formatting, like italic() and atop(), it's actually a part of plotmath and so you need to wrap it in an expression. eg:
plot(0, main = expression(atop(over,italic(under))))
If you've tried out ?italic or ?atop, you've probably noticed it takes you straight to the plotmath manual page, where a bunch of other functions are listed.
What about substitute() ? Well in my previous example, you'll notice I used strings directly to write 'over' and 'under', without putting them within quotes. This is because of the special expression() environment.
So if you need to put whatever is inside a variable in your text (rather than the variable name) then you put your expression inside a substitute() and give it the arguments. eg:
plot(0, main = substitute(atop(oo,italic(under))), list(oo='over2')))
Note that we don't put substitute around the expression block but replace it entirely.
Finally, where does paste() come in all this ? Well, paste is the glue (pun intended) with any text not dealt with by plotmath.
So if you need text before or after math symbols (or formatted text), you paste() things together within the expression (or substitute) environment. eg :
plot(0, main = substitute(paste("b4", atop(oo,italic(under)), aft),
list(oo='over', aft = 'after3')))
As before, if you want to paste the content of a variable, you need substitute.
And Voilà that's most of the plotmath you'll ever need!
For any other symbols, or functions, have look at ?plotmath
I make some plots with R and use bquote because I need variables for the main of the plot. However, the main is no longer bold but I want it to be bold. I defined the main as follows:
title = bquote(atop("Empirical Pricing Kernel at Date",~.(EndDate)~"with Index Price"~.(ST)~"€"))
plot(temp, EPK, type="l", main = title)
Enddate contains "2014-08-01" as date and ST is just numeric with 9210.08.
Is there any way to make it bold with or without bquote? I'd like to find a solution with bquote because it's very convenient when using subscripts.
My problem is that I am using it in a par-plot with two plots and the other plot needs no special things in it's main. So, the main is bold. I even tried to just put bquote around it in order to get the same font size but it stayed bold.
I prefer to use what I think of as "pure plotmath" so I use tilde's instead of spaces and use no quotes. I suspect it was the leading tilde in the second argument to bquote that was throwing the error. In plotmath the tildes need something on either side: If you really need a none-displayed something you can always use phantom(0) but why bother in this case?
bquote(atop(Empirical~Pricing~Kernel~at~Date,
bold(.(EndDate))~with~Index~Price~.(ST)~"€"
) )
Test:
EndDate="2014-08-01";ST=9210.08
title = bquote(atop(Empirical~Pricing~Kernel~at~Date, bold(.(EndDate))~with~Index~Price~.(ST)~"€"))
plot(1,1, type="l", main = title)
I would like to have the title for the plot in two lines, but this does not work, why? and how can I make it work?
CVal<-1
SumEpsVal<-2
plot(1:10, main=bquote(paste("C=", .(CVal), " \n ", sum(xi), "=", .(SumEpsVal) )))
This here works:
plot(1:10, main=paste("C=1", "\n", "SumXi=2"))
I guess bquote makes something wrong... (look up ?bquote)
I tried to change environment in bqoute (the where-argument) but I don't know which environment to take.
BTW:
plot(1:10, main=bquote(paste("C=", .(CVal), "bla \n ", sum(xi), "=", .(SumEpsVal) )))
makes something crazy with the "bla".
Personally I would use mtext as already suggested. But if you really want it to be a one-liner, you can "cheat" bquote by using atop:
plot(1:10, main=
bquote(atop(paste("C=",.(CVal)), paste(sum(xi),"=",.(SumEpsVal)))))
It even aligns both lines neatly to the center.
The root issue is that plotmath does not support newlines within the
expressions to be output.
Control characters (e.g. \n) are not interpreted in character strings in plotmath,
unlike normal plotting.
You really need to create and output each line separately.
For example :
Lines <- list(bquote(paste("C=", .(CVal))),
bquote(paste(sum(xi), "=", .(SumEpsVal))))
Now output each line The text in the list is converted to expressions do.call
mtext(do.call(expression, Lines),side=3,line=0:1)
One way to achieve this is to use mtext to add an additional line under the main title as follows:
plot(1:10, main=bquote(paste("C=", .(CVal))))
mtext(bquote(paste(sum(xi), "=", .(SumEpsVal) )),side=3,line=0)
There may be a prettier solution, but perhaps this is enough for your needs.
I want to split a line in an R script over multiple lines (because it is too long). How do I do that?
Specifically, I have a line such as
setwd('~/a/very/long/path/here/that/goes/beyond/80/characters/and/then/some/more')
Is it possible to split the long path over multiple lines? I tried
setwd('~/a/very/long/path/here/that/goes/beyond/80/characters/and/
then/some/more')
with return key at the end of the first line; but that does not work.
Thanks.
Bah, comments are too small. Anyway, #Dirk is very right.
R doesn't need to be told the code starts at the next line. It is smarter than Python ;-) and will just continue to read the next line whenever it considers the statement as "not finished". Actually, in your case it also went to the next line, but R takes the return as a character when it is placed between "".
Mind you, you'll have to make sure your code isn't finished. Compare
a <- 1 + 2
+ 3
with
a <- 1 + 2 +
3
So, when spreading code over multiple lines, you have to make sure that R knows something is coming, either by :
leaving a bracket open, or
ending the line with an operator
When we're talking strings, this still works but you need to be a bit careful. You can open the quotation marks and R will read on until you close it. But every character, including the newline, will be seen as part of the string :
x <- "This is a very
long string over two lines."
x
## [1] "This is a very\nlong string over two lines."
cat(x)
## This is a very
## long string over two lines.
That's the reason why in this case, your code didn't work: a path can't contain a newline character (\n). So that's also why you better use the solution with paste() or paste0() Dirk proposed.
You are not breaking code over multiple lines, but rather a single identifier. There is a difference.
For your issue, try
R> setwd(paste("~/a/very/long/path/here",
"/and/then/some/more",
"/and/then/some/more",
"/and/then/some/more", sep=""))
which also illustrates that it is perfectly fine to break code across multiple lines.
Dirk's method above will absolutely work, but if you're looking for a way to bring in a long string where whitespace/structure is important to preserve (example: a SQL query using RODBC) there is a two step solution.
1) Bring the text string in across multiple lines
long_string <- "this
is
a
long
string
with
whitespace"
2) R will introduce a bunch of \n characters. Strip those out with strwrap(), which destroys whitespace, per the documentation:
strwrap(long_string, width=10000, simplify=TRUE)
By telling strwrap to wrap your text to a very, very long row, you get a single character vector with no whitespace/newline characters.
For that particular case there is file.path :
File <- file.path("~",
"a",
"very",
"long",
"path",
"here",
"that",
"goes",
"beyond",
"80",
"characters",
"and",
"then",
"some",
"more")
setwd(File)
The glue::glue function can help. You can write a string on multiple lines in a script but remove the line breaks from the string object by ending each line with \\:
glue("some\\
thing")
something
I know this post is old, but I had a Situation like this and just want to share my solution. All the answers above work fine. But if you have a Code such as those in data.table chaining Syntax it becomes abit challenging. e.g. I had a Problem like this.
mass <- files[, Veg:=tstrsplit(files$file, "/")[1:4][[1]]][, Rain:=tstrsplit(files$file, "/")[1:4][[2]]][, Roughness:=tstrsplit(files$file, "/")[1:4][[3]]][, Geom:=tstrsplit(files$file, "/")[1:4][[4]]][time_[s]<=12000]
I tried most of the suggestions above and they didn´t work. but I figured out that they can be split after the comma within []. Splitting at ][ doesn´t work.
mass <- files[, Veg:=tstrsplit(files$file, "/")[1:4][[1]]][,
Rain:=tstrsplit(files$file, "/")[1:4][[2]]][,
Roughness:=tstrsplit(files$file, "/")[1:4][[3]]][,
Geom:=tstrsplit(files$file, "/")[1:4][[4]]][`time_[s]`<=12000]
There is no coinvent way to do this because there is no operator in R to do string concatenation.
However, you can define a R Infix operator to do string concatenation:
`%+%` = function(x,y) return(paste0(x,y))
Then you can use it to concat strings, even break the code to multiple lines:
s = "a" %+%
"b" %+%
"c"
This will give you "abc".
This will keep the \n character, but you can also just wrap the quote in parentheses. Especially useful in RMarkdown.
t <- ("
this is a long
string
")
I do this all of the time. Use the paste0() function.
Rootdir = "/myhome/thisproject/part1/"
Subdir = "subdirectory1/subsubdir2/"
fullpath = paste0( Rootdir, Subdir )
fullpath
> fullpath
[1] "/myhome/thisproject/part1/subdirectory1/subsubdir2/"