How to separate graphs and then plot their on one graphical window? - r

I have three time series md1, md2, md3, three ARIMA models f1, f2, f3. I'd like to plot AR- и МA-roots of ARIMA models in one graphical window. I have tried:
library(forecast)
md1 <- runif(100, 0, 1)
md2 <- runif(100, 0, 1)
md3 <- runif(100, 0, 1)
f1<-arima(md1,order=c(1,1,0))
f2<-arima(md2,order=c(1,1,0))
f3<-arima(md3,order=c(2,1,2))
par(mfrow = c(1,3))
# AR- и МA-roots of ARIMA models
plot(f1) # one graph
plot(f2) # one graph
plot(f3) # two graphs
As the result, I see the last plot only, i.e. plot(f3). Of course, I can add the windows() command
plot(f2); windows()
and make a new graphical window for plot(f3). Also, I have tried to change options of the par() function, likes
par(mfrow = c(2,2))
and tried to create a new object
p3 <- plot(f3)
but expected result wasn't achieved.
Question. How to separate two graphs generated by the plot(f3) command?
Expected result:

I have found the answer on my question here. This is the code which was not included to the package forecast by the author.

Related

How do I plot multiple lines on the same graph?

I am using the R. I am trying to use the "lines' command in ggplot2 to show the predicted values vs. the actual values for a statistical model (arima, time series). Yet, when I ran the code, I can only see a line of one color.
I simulated some data in R and then tried to make plots that show actual vs predicted:
#set seed
set.seed(123)
#load libraries
library(xts)
library(stats)
#create data
date_decision_made = seq(as.Date("2014/1/1"), as.Date("2016/1/1"),by="day")
date_decision_made <- format(as.Date(date_decision_made), "%Y/%m/%d")
property_damages_in_dollars <- rnorm(731,100,10)
final_data <- data.frame(date_decision_made, property_damages_in_dollars)
#aggregate
y.mon<-aggregate(property_damages_in_dollars~format(as.Date(date_decision_made),
format="%W-%y"),data=final_data, FUN=sum)
y.mon$week = y.mon$`format(as.Date(date_decision_made), format = "%W-%y")`
ts = ts(y.mon$property_damages_in_dollars, start = c(2014,1), frequency = 12)
#statistical model
fit = arima(ts, order = c(4, 1, 1))
Here were my attempts at plotting the graphs:
#first attempt at plotting (no second line?)
plot(fit$residuals, col="red")
lines(fitted(fit),col="blue")
#second attempt at plotting (no second line?)
par(mfrow = c(2,1),
oma = c(0,0,0,0),
mar = c(2,4,1,1))
plot(ts, main="as-is") # plot original sim
lines(fitted(fit), col = "red") # plot fitted values
legend("topleft", legend = c("original","fitted"), col = c("black","red"),lty = 1)
#third attempt (plot actual, predicted and 5 future values - here, the actual and future values show up, but not the predicted)
pred = predict(fit, n.ahead = 5)
ts.plot(ts, pred$pred, lty = c(1,3), col=c(5,2))
However, none of these seem to be working correctly. Could someone please tell me what I am doing wrong? (note: the computer I am using for my work does not have an internet connection or a usb port - it only has R with some preloaded packages. I do not have access to the forecast package.)
Thanks
Sources:
In R plot arima fitted model with the original series
R fitted ARIMA off by one timestep? pkg:Forecast
Plotting predicted values in ARIMA time series in R
You seem to be confusing a couple of things:
fitted usually does not work on an object of class arima. Usually, you can load the forecast package first and then use fitted.
But since you do not have acces to the forecast package you cannot use fitted(fit): it always returns NULL. I had problems with fitted
before.
You want to compare the actual series (x) to the fitted series (y), yet in your first attempt you work with the residuals (e = x - y)
You say you are using ggplot2 but actually you are not
So here is a small example on how to plot the actual series and the fitted series without ggplot.
set.seed(1)
x <- cumsum(rnorm(10))
y <- stats::arima(x, order = c(1, 0, 0))
plot(x, col = "red", type = "l")
lines(x - y$residuals, col = "blue")
I Hope this answer helps you get back on tracks.

Trying to find a way to combine IRT info plots from 3 different mirt models in R in the same

I am looking to combine all three" test information function" lines (one for each model) into one and the same graph. I have a data set of category 1-5 Likert responses in 400 rows in sets of 8 columns (one for each item). I have ran three IRT models on these sets using mirt package in R, and produced test info plots. I would like to combine IRT test info plots from three different (graded response) models, three lines, in one and the same grid.
plot(PFgrmodel29, type = 'info', xlim = c(-4, 4), ylim=c(0,85))
plot(PFgrmodel43, type = 'info', xlim = c(-4, 4), ylim=c(0,85))
plot(PFgrmodel57, type = 'info', xlim = c(-4, 4), ylim=c(0,85))
Example of test info plot:
How can I achieve this with mirt, lattice, ggplot2 or similar?
Your plots from the mirt package are a lattice object, so you can try using latticeExtra, since you did not provide your dataset, I provide an example code below using the example dataset in the package:
library(mirt)
library(latticeExtra)
fulldata <- expand.table(LSAT7)
mod1 <- mirt(fulldata,1,SE=TRUE)
mod2 <- mirt(fulldata,1, itemtype = 'Rasch')
mod3 <- mirt(fulldata,1,itemtype='ideal')
key=list(columns=2,
text=list(lab=c("mod1","mod2","mod3")),
lines=list(lwd=4, col=c("blue","orange","red"))
)
p1 = plot(mod1,type="info",key=key)
p2 = update(plot(mod2,type="info"),col="orange")
p3 = update(plot(mod3,type="info"),col="red")
p1+p2+p3
That is just beautiful! Works like a charm, except I needed to add ylim=c(0,100) to modify the y axis (taller) to fit the data. I thought that placing the model with the highest info curve first ( as mod1) would do it, but no. Thank you Stupidwolf so much for providing the code!! No need for latticeExtra package.
ALso I had to retain the "model" part of the code for this to work:
model <- 'F = 1-5 PRIOR = (5, g, norm, -1.5, 3)'
My code looks like this now:
library(mirt)
library(latticeExtra)
model <- 'F = 1-5 PRIOR = (5, g, norm, -1.5, 3)'
mod1 <- mirt(PFdata57,1,itemtype="graded", SE=TRUE)
mod2 <- mirt(PFdata43,1,itemtype="graded", SE=TRUE)
mod3 <- mirt(PFdata29,1,itemtype="graded", SE=TRUE)
key=list(columns=1,
text=list(lab=c("P57/PF Short form 8a","P43/PF Short form 6a","P29/PF Short form 4a")),
lines=list(lwd=4, col=c("blue","orange","red")))
p1 = plot(mod1,type="info",key=key,xlim=c(-4,4),ylim=c(0,85))
p2 = update(plot(mod2,type="info"),col="orange")
p3 = update(plot(mod3,type="info"),col="red")
p1+p2+p3

Replay recorded plot with new layout in R

I am trying to create and record plots in a 1x1 device:
par(mfrow = c(1, 1) )
plot(rnorm(10) )
p1 <- recordPlot()
plot(rnorm(20) )
p2 <- recordPlot()
and then to put them in a new layout (e.g., a 1x2 device):
par(mfrow = c(1, 2) )
p1
p2
However, this produce the same effect (i.e., plotting each plot in a 1x1 device). It seems replaying plots uses the original layout (graphical parameters) that was in effect when they were recorded.
Is there some method that allows a saved plot to be replayed in a new layout ?
NB: I am aware this would be easier via ggplot2, but my question is about base plots.
I did some digging, and I don't think this is possible. I used the following to look at what attributes are available inside the object. None of them seemed to indicate the layout could be adjusted.
summary(p1)
p1[[1]]
p1[[2]]
If you need the same plot across two different layouts could you use set.seed() to recreated the same plot? See the example below.
par(mfrow = c(1, 1))
set.seed(1234)
plot(rnorm(10))
par(mfrow = c(1, 2))
set.seed(1234)
plot(rnorm(10))
I'd be interested to see if anyone else has a better answer!

Plotting quantile regression by variables in a single page

I am running quantile regressions for several independent variables separately (same dependent). I want to plot only the slope estimates over several quantiles of each variable in a single plot.
Here's a toy data:
set.seed(1988)
y <- rnorm(50, 5, 3)
x1 <- rnorm(50, 3, 1)
x2 <- rnorm(50, 1, 0.5)
# Running Quantile Regression
require(quantreg)
fit1 <- summary(rq(y~x1, tau=1:9/10), se="boot")
fit2 <- summary(rq(y~x2, tau=1:9/10), se="boot")
I want to plot only the slope estimates over quantiles. Hence, I am giving parm=2 in plot.
plot(fit1, parm=2)
plot(fit2, parm=2)
Now, I want to combine both these plots in a single page.
What I have tried so far;
I tried setting par(mfrow=c(2,2)) and plotting them. But it's producing a blank page.
I have tried using gridExtra and gridGraphics without success. Tried to convert base graphs into Grob objects as stated here
Tried using function layout function as in this document
I am trying to look into the source code of plot.rqs. But I am unable to understand how it's plotting confidence bands (I'm able to plot only the coefficients over quantiles) or to change mfrow parameter there.
Can anybody point out where am I going wrong? Should I look into the source code of plot.rqs and change any parameters there?
While quantreg::plot.summary.rqs has an mfrow parameter, it uses it to override par('mfrow') so as to facet over parm values, which is not what you want to do.
One alternative is to parse the objects and plot manually. You can pull the tau values and coefficient matrix out of fit1 and fit2, which are just lists of values for each tau, so in tidyverse grammar,
library(tidyverse)
c(fit1, fit2) %>% # concatenate lists, flattening to one level
# iterate over list and rbind to data.frame
map_dfr(~cbind(tau = .x[['tau']], # from each list element, cbind the tau...
coef(.x) %>% # ...and the coefficient matrix,
data.frame(check.names = TRUE) %>% # cleaned a little
rownames_to_column('term'))) %>%
filter(term != '(Intercept)') %>% # drop intercept rows
# initialize plot and map variables to aesthetics (positions)
ggplot(aes(x = tau, y = Value,
ymin = Value - Std..Error,
ymax = Value + Std..Error)) +
geom_ribbon(alpha = 0.5) +
geom_line(color = 'blue') +
facet_wrap(~term, nrow = 2) # make a plot for each value of `term`
Pull more out of the objects if you like, add the horizontal lines of the original, and otherwise go wild.
Another option is to use magick to capture the original images (or save them with any device and reread them) and manually combine them:
library(magick)
plots <- image_graph(height = 300) # graphics device to capture plots in image stack
plot(fit1, parm = 2)
plot(fit2, parm = 2)
dev.off()
im1 <- image_append(plots, stack = TRUE) # attach images in stack top to bottom
image_write(im1, 'rq.png')
The function plot used by quantreg package has it's own mfrow parameter. If you do not specify it, it enforces some option which it chooses on it's own (and thus overrides your par(mfrow = c(2,2)).
Using the mfrow parameter within plot.rqs:
# make one plot, change the layout
plot(fit1, parm = 2, mfrow = c(2,1))
# add a new plot
par(new = TRUE)
# create a second plot
plot(fit2, parm = 2, mfrow = c(2,1))

labeling axis for parametric terms with plot.gam

I am trying to plot my gam results. The plotting works very well for all the smooth terms (in my case terms 1 to 8) but if I want to plot parametric terms (from 9 onwards), I can't change the axis labels. No matter if I use plot, plot.gam, termplot or text I can't do it. Any tips? Below is the code example
par(mfrow=c(3,3), oma=c(1,1,1,1),pty="s",mar=c(4.5,4.5,1,1))
# the first three graphs work perfectly
plot.gam(model$gam,select=1,scale=0,pers=TRUE,all.terms=T,shade=T,xlab="Water depth",ylab="")
plot.gam(model$gam,select=2,scale=0,pers=TRUE,all.terms=T,shade=T,xlab="Bottom current speed",ylab="")
plot.gam(model$gam,select=3,scale=0,pers=TRUE,all.terms=T,shade=T,xlab="Substance",ylab="")
# this graph for the parametric term is plotted but I cannot change axis labels
plot.gam(model$gam,select=9,scale=0,pers=T,all.terms=T,shade=T,xlab="AIS",ylab="")
If you are using RStudio you can check the source code of plot.gam by hitting the F2 button. In R execute the plot.gam without brackets. Then you can find, that plot() is replaced by termplot() for some select values.
Thus, to maipulate the x-axis labels you have to use xlabs instead of xlab.
require(mgcv)
pa <- c(1, rep(0, 9))
term_A <- runif(10, 9, 15)
term_B <- runif(10, 1, 25)
data <- as.data.frame(cbind(pa, term_A, term_B))
mod <- gam(pa ~ s(term_A, k=3) + term_B, family=binomial, data=data)
summary(mod)
par(mfrow=c(2, 2))
# xlab=""
plot.gam(mod, select=1, all.terms=T, shade=T, xlab="your own lab title", ylab="")
# xlabs=""
plot.gam(mod, select=2, all.terms=T, shade=T, xlabs="your own lab title", ylab="")

Resources