R: plotmath expression symbols not showing up in interaction plot - r

For some reason, my interaction plots don't seem to show the greek symbols (latex) in R markdown (using R studio). The code I am using is reproduced below. Why are the expression() functions not working? Any suggestions?
with(ba_results, interaction.plot(as.factor(f1), as.factor(f2),
y,
type = "b",
pch = c(18, 19, 24),
fixed = TRUE,
xlab = "Scale factor",
ylab = "Mean Response",
trace.label = expression(mu_e),
main = paste("Interaction plot of",
expression(mu[e]),
"f1")))

For the title, wrap the whole thing in expression. For example, main = expression(paste("Interaction plot of ", mu[e], " f1")) or main = expression(Interaction~plot~of~mu[e]~f1).
For the trace.label, the expression is not being parsed properly. It looks like the problem is this line in the code for interaction.plot:
text(xleg, ylim[2L] - 0.05 * yrng, paste(" ", trace.label), adj = 0)
So trace.label is wrapped in paste which turns the expression back into a text string. For example:
expression(mu[e])
# expression(mu[e])
paste(" ", expression(mu[e]))
# " mu[e]"
As a workaround, you can modify the function to use trace.label as is. To do that, get the code for interaction.plot by typing interaction.plot in the console. Copy the code into a new R script file and assign the function a new name like my_interaction_plot. Then change the line above to this:
text(xleg, ylim[2L] - 0.05 * yrng, trace.label, adj = 0)
This change will result in expression(mu[e]) being parsed properly.
Now just use my_interaction_plot instead of interaction.plot like this:
with(ba_results,
my_interaction_plot(as.factor(f1), as.factor(f2), y, type = "b",
pch = c(18, 19, 24), fixed = TRUE,
xlab = "Scale factor", ylab = "Mean Response",
trace.label = expression(mu_e),
main = expression(paste("Interaction plot of ", mu[e], " f1"))))

Related

Question about the functions `get_test_label` and `get_pwc_label` from the `rstatix` package

I have recently become familiar with the rstatix package. Below is an example code using functions from this package.
library(tidyverse)
library(rstatix)
library(ggpubr)
set.seed(1111)
n=100
df = tibble(
x1 = rnorm(n, 0, 1.1),
x2 = rnorm(n, 0.2, .1),
x3 = rnorm(n, -.2, .2),
x4 = rnorm(n, 0, 2),
) %>% pivot_longer(x1:x4)
df
pwc = df %>%
pairwise_t_test(value~name, paired = TRUE,
p.adjust.method = "bonferroni") %>%
add_xy_position(x = "name") %>%
mutate(name=group1,
lab = paste(p, " - ", p.adj.signif))
res.test = df %>% anova_test(value~name)
df %>% ggplot(aes(name, value))+
geom_boxplot(alpha=0.6)+
stat_pvalue_manual(pwc, step.increase=0.05, label = "lab")+
labs(title = get_test_label(res.test, detailed = TRUE),
subtitle = get_pwc_label(pwc))
However, I noticed that functions like get_test_label or get_pwc_label do not return text, but commands to prepare the text.
For example, calling get_test_label(res.test, detailed = TRUE) gives this:
paste("Anova, ", italic("F"), "(3,396)", " = ",
"5.26, ", italic("p"), " = ", "0.001",
paste(", ", eta["g"]^2, " = ", 0.04), "")
In turn, calling get_pwc_label(pwc) will result in:
paste("pwc: ", bold(c(t_test = "T test")), "; p.adjust: ",
bold("Bonferroni"))
Now my question, basically two questions.
What could be the reason these functions do not return text but commands?
How to make your own function that returns similar commands.
R's graphics devices use the syntax defined in ?plotmath to distinguish between literal and formatted text. A basic feature of this syntax is that strings define literal text while functions define operations on text, such as juxtaposition and formatting (changing fonts, adding diacritics, getting whitespace right in mathematical formulae, etc.). What you are seeing, then, are unevaluated compositions of functions and strings defining formatted text. These are typically called plotmath expressions.
I could provide you with a basic example showing how different expressions translate to graphical output, but there is an excellent demo built into R: just run demo("plotmath") in an interactive R session and follow the prompts.
Functions that you can use to create expressions like the ones you are seeing include quote, substitute, bquote, and str2lang. You would probably use one of these to format, e.g., a plot title. Here is how I would use each function to generate the expression paste("Michaelis constant: ", italic("K")["M"], " = ", 0.015).
quote(
paste("Michaelis constant: ", italic("K")["M"], " = ", 0.015)
)
substitute(
paste("Michaelis constant: ", italic(sym)[sub], " = ", val),
list(sym = "K", sub = "M", val = 0.015)
)
sym <- "K"
sub <- "M"
val <- 0.015
bquote(
paste("Michaelis constant: ", italic(.(sym))[.(sub)], " = ", .(val))
)
str2lang(
'paste("Michaelis constant: ", italic("K")["M"], " = ", 0.015)'
)
The differences are subtle, so it could be worth browsing each function's help page and running the examples there.
Functions that you can use to create expression vectors include expression and str2expression. You would use one of these to format one or more labels at once, e.g., when defining axis tick labels. Here is how I would use each function to format labels for ticks at increasing powers of 10:
expression(10^0, 10^1, 10^2, 10^3, 10^4, 10^5)
str2expression(paste0(10, "^", 0:5))
Finally, here is a fun plot putting everything together:
plot.new()
plot.window(c(0, 1), c(1, 100000), log = "y")
box()
title(main = quote(paste("Michaelis constant: ", italic("K")["M"], " = ", 0.015)))
axis(side = 2, at = 10^(0:5), labels = str2expression(paste0(10, "^", 0:5)), las = 1)
text(x = seq(0, 1, by = 0.2), y = 10^(0:5), labels = str2expression(sprintf('%s("%s")', c("plain", "bold", "italic", "bolditalic", "symbol", "underline"), month.abb[1:6])))
For even more examples, take a look at ?plotmath.

R: How to batch create multiple copies of an .R script file with different variable names?

This is my first post here and I am trying to follow the guidelines to the best of my knowledge, so please bear with me.
I want to create a large number of similar .R script files which differ only in the variable names used and in the strings that mention these variables. Of course, this can also be achieved via search & replace but I was wondering whether there is a more convenient solution to create a bunch of them more quickly.
Let's take this made up script (the actual data is irrelevant here):
prefix.AnExemplaryRandomVariable <- rnorm(n = 100, mean = 0, sd = 1)
AnotherRandomVariable.suffix <- rnorm(n = 100, mean = 10, sd = 3)
plot(prefix.AnExemplaryRandomVariable, AnotherRandomVariable.suffix,
type = "p", pch = "*", xlab = "An Exemplary Random Variable",
ylab = "Another Random Variable", main = "A plot of An Exemplary
Random Variable and Another Random Variable")
My idea was to define two vectors with k new names for each one.
newNamesVar1 <- c("prefix.FirstVariable", "prefix.SomeData")
newNamesVar2 <- c("SecondVariable.suffix", "CannotThinkOfMoreNames.suffix")
The result I am looking for are k new .R files that look like this:
prefix.FirstVariable <- rnorm(n = 100, mean = 0, sd = 1)
SecondVariable.suffix <- rnorm(n = 100, mean = 10, sd = 3)
plot(prefix.FirstVariable, SecondVariable.suffix, type = "p",
pch = "*", xlab = "First Variable", ylab = "Second Variable",
main = "A plot of First Variable and Second Variable")
and
prefix.SomeData <- rnorm(n = 100, mean = 0, sd = 1)
CannotThinkOfMoreNames.suffix <- rnorm(n = 100, mean = 10, sd = 3)
plot(prefix.SomeData, CannotThinkOfMoreNames.suffix, type = "p",
pch = "*", xlab = "Some Data", ylab = "Cant Think Of More Names",
main = "A plot of Some Data and Cannot Think Of More Names")
I see the following two challenges:
Replacing the original variable names with the corresponding vector entries
Checking any strings for similarities with the original variable names and replacing them while keeping the syntax and format (case sensitivity, spacing,...) intact.
This is the first time I am trying to use R for anything beyond actual data analysis, so I cannot even provide much of a code draft. I was able to get the variable names with ls(), but I do not have the slightest clue about what to do next, mainly because the changes are not to be applied to the file that is currently active but to a completely new one.
Any solutions, tips, hints or nudges are appreciated!
Thank you!
Here's one method.
Setup for this answer:
writeLines('
prefix.AnExemplaryRandomVariable <- rnorm(n = 100, mean = 0, sd = 1)
AnotherRandomVariable.suffix <- rnorm(n = 100, mean = 10, sd = 3)
plot(prefix.AnExemplaryRandomVariable, AnotherRandomVariable.suffix,
type = "p", pch = "*", xlab = "An Exemplary Random Variable",
ylab = "Another Random Variable",
main = "A plot of An Exemplary Random Variable and Another Random Variable")
', "template.R")
Table of replacement values to use, where the column name indicates the template string, and the column values are the replacement text.
replacements <- data.frame(
"An Exemplary Random Variable" = c("First Variable", "Some Data"),
"Another Random Variable" = c("Second Variable", "Cannot Think Of More Names"),
check.names = FALSE
)
replacements
# An Exemplary Random Variable Another Random Variable
# 1 First Variable Second Variable
# 2 Some Data Cannot Think Of More Names
The Work that replaces each template string from the template.R, makes the replacement, ultimately storing into new files.
code <- readLines("template.R")
for (row in seq_len(nrow(replacements))) {
newcode <- code
for (col in seq_along(replacements)) {
if (!is.na(replacements[row,col])) {
ptn1 <- colnames(replacements)[col] # original
ptn2 <- gsub(" +", "", ptn1) # "Title Case Sentence" to "TitleCaseSentence"
repl1 <- replacements[row,col]
repl2 <- gsub(" +", "", repl1)
newcode <- gsub(paste0("\\b", ptn1, "\\b"), repl1,
gsub(paste0("\\b", ptn2, "\\b"), repl2, newcode))
}
}
writeLines(newcode, sprintf("code_%s.R", row))
}
This has the added functionality that if the replacement string (value within a particular cell in replacements) is NA, then no replacement will be attempted for that pattern.
Output:
code_1.R
prefix.FirstVariable <- rnorm(n = 100, mean = 0, sd = 1)
SecondVariable.suffix <- rnorm(n = 100, mean = 10, sd = 3)
plot(prefix.FirstVariable, SecondVariable.suffix,
type = "p", pch = "*", xlab = "First Variable",
ylab = "Second Variable",
main = "A plot of First Variable and Second Variable")
code_2.R
prefix.SomeData <- rnorm(n = 100, mean = 0, sd = 1)
CannotThinkOfMoreNames.suffix <- rnorm(n = 100, mean = 10, sd = 3)
plot(prefix.SomeData, CannotThinkOfMoreNames.suffix,
type = "p", pch = "*", xlab = "Some Data",
ylab = "Cannot Think Of More Names",
main = "A plot of Some Data and Cannot Think Of More Names")
Limitations:
pattern strings must be contiguous on their own line, so notice that I changed the template main= string to not span two lines
pattern strings must not be immediately preceded/followed by letters; the use of \\b (regex word boundary) allows for some characters (like the literal .), but this makes no attempt to be any fancier
Edited: after I finished, I realized that it might be easier to define the patterns and replacement strings with the spaces, and then remove the spaces for the second (TitleCase) pattern. This way one avoids some ambiguity and trickery of splitting a string by title-case. It also allows for your patterns or replacements to be not title case.

Change sub-titles in lattice/densityplot

I was working in lattice/densityplot and want to change the "in", "out" sub-titles to "inpatinet", "outpatient".
Thank you. The image and code below:
colors = c("black", "blue")
lines = c(1,2) #1
points = c(16,17)
key.trans <- list(title="Gender",
corner = c(0.90, 0.90),
#space="bottom", columns=2, #2
text=list(c("Female","Male")),
#points=list(pch=points, col=colors),
lines=list(col=colors, lty=lines),
cex.title=1, cex=.9)
densityplot(~ Age_yrs|Location_type, groups=Sex,
data = subset(all_isolates_inc_ATCC, Age_yrs<100 &
Institution=="P06"
& Organism=="eco"
& Location_type!="unk"),
xlab = "Age, years",
lty=lines, col=colors,
lwd=2,
plot.points = FALSE,
#jitter=.00005,
key=key.trans)
The strip names can be changed in the function with the strip.custom function. A related question was asked in Change text on strips in lattice plots. In your case you would add the following argument to your densityplot() call:
strip = strip.custom(factor.levels = c("In patient", "Out patient"))
More information is found with help for strip.default although help for strip.custom gets you there as well.

R: subscript text as a variable

In R I would like to create several plots in a for-loop. The y-axis label is supposed to exhibit a subscript, in which the subscript text should vary along with the loop-iterator.
For subscripting a label, I previously used "expression". However, as you can see in the minimal example, the subscript in the expression cannot be indexed the way I thought it would (instead of printing "1", "2", "3" it simply prints "i"). Do you have an idea on how to fix this (either by using the expression function or any other text function able to produce subscripts)?
Minimal code:
# minimal example code
Data = matrix(ncol = 4, nrow = 1000)
colnames(Data) = c("time", "k1", "k2", "k3")
Data[,1] = seq(0.1,100,0.1)
Data[,2] = sin(Data[,1])
Data[,3] = cos(Data[,1])
Data[,4] = tan(Data[,1])
for(i in 1:3) {
plot(Data[,1], Data[,(1+i)], type = "l", lwd = 2, xlab = "time", ylab = expression("k" [i]))
}
Thank you!
Use bquote. Stolen from this SO:
Subscripts in plots in R
for(i in 1:3) {
plot(Data[,1], Data[,(1+i)], type = "l", lwd = 2, xlab = "time", ylab = bquote(k[.(i)]))
}
It has very strange syntax of: bquote(WORD [ . (OBJECT) ]. Note that WORD is not quoted and the dot. I believe the . is referring to what environment to go find OBJECT.

How to change the color and width of lines with par function in R

I have a question about the par function in R.
I want to change the color and/or width of a line in a graph with par function. (I am using par function because the gaps.plot command below does not allow "col" option to be included. The gaps.plot command is used after the synth command).
So, I used the following command. But I noticed that the lines of the BOX are changed rather than the lines of the GRAPHS.
synth1<-read.csv(file="C:\\Users\\Research\\R\\synthinR_v4.csv",header=TRUE)
attach(synth1)
library("Synth")
dataprep.out34 <- dataprep(foo = synth1, predictors = c("lncdsales", "md1", "md2","md3", "md4", "md5", "md6", "md7", "md8", "md9", "md10", "md11", "yd1", "yd2", "yd3", "yd4", "yd5", "yd6", "yd7", "yd8"), predictors.op = "mean", time.predictors.prior = -13:1, dependent = "lndigital", unit.variable = "artistalbumcode", time.variable = "release", treatment.identifier = 34, controls.identifier = c(1:33, 35:49), time.optimize.ssr = -13:1, time.plot = -13:25)
synth.out34 <- synth(data.prep.obj = dataprep.out34, method = "BFGS")
par(lwd = 2, col="#cccccc")
gaps.plot(synth.res = synth.out34, dataprep.res = dataprep.out34, Ylab = " Log Digital Sales ", Xlab = "Release", Ylim = c(-7, 7) , Main = NA)
Does anyone know how to fix this problem??
Thank you in advance for your willingness to help. I greatly appreciate it!
The col argument to par sets the default plotting colour (i.e. when col is not explicitly specified in plotting calls), but unfortunately col = "black" is hard-coded into the source of gaps.plot.
You can make a modified copy of the function by either (1) viewing the source (F2 in RStudio, or just executing gaps.plot), editing it and assigning it to a new object, or (2) doing something like the following:
gaps.plot2 <- eval(parse(text=gsub('col = "black"', 'col = "red"',
deparse(Synth:::gaps.plot))))
and then using gaps.plot2 as you would use gaps.plot:
gaps.plot2(synth.res = synth.out34, dataprep.res = dataprep.out34,
Ylab = " Log Digital Sales ", Xlab = "Release", Ylim = c(-7, 7) ,
Main = NA)
Alter the lwd similarly. For example to make lines red and have width of 3, use nested gsub calls like this:
gaps.plot2 <- eval(parse(text=gsub('lwd = 2', 'lwd = 3',
gsub('col = "black"', 'col = "red"',
deparse(Synth:::gaps.plot)))))

Resources