Blank page arrange_ggsurvplots Rstudio - r

Using the function arrange_ggsurvplots() in order to have 4 ggsurvplot() in a 2x2 representation, but using this function, it builds a blank page before the plot of the 4 groups graphs.
I build 4 different survfit as:
library(survminer)
fit_1 <- survfit(Surv(...) ~ ..., data = data_1)
splots[[1]] <- ggsurvplot(fit_1,...)
In order to arrange it all:
arrange_ggsurvplots(splots, print = TRUE,
ncol = 2, nrow = 2)

You need to save the plot as an object, and then save it to disk with ggsave():
myplots_out <- arrange_ggsurvplots(
myplots,
print = FALSE,
ncol = 2,
nrow = 2,
title = "MySuperPlots")
ggsave(
myplots_out,
file = "Results/Survival.pdf",
width = 10.5,
height = 5)
That will avoid the production of the blank first page in the output file.

Related

saving and naming files in R automatically based on input filename

I have generated several Utilisation Distributions (UD) with AdehabitatHR and stored them as Geotiffs. I am now using the same UDs with the Lattice package to generate some maps and saving them to a high-res tiff image with LZW compression. Problem is that I have literally hundreds of maps to make, save and name. Is there a way automatically do this once i have loaded all the necessary files from a directory? Each one of my UDs has the following structure of the filename "UD_resolution_species_area_year_season. tif" and in the final name I give to my map I would like to keep the same structure (or entire filename) but add the prefix "blablabla_" e.g. "blablabla_UD_resolution_species_area_year_season.tiff". The image also include a main name, a capital letter, which should also change.
At the moment I am using the following:
rlist = list.files(getwd(), pattern = "tif$", full.names = FALSE)
for (i in rlist) {
assign(unlist(strsplit(i, "[.]"))[1], raster(i))
}
shplist = list.files(getwd(), pattern = "shp$", full.names = FALSE)
for (i in shplist) {
assign(unlist(strsplit(i, "[.]"))[1], readOGR(i))
}
UD <- 'UD_resolution_species_area_year_season'
ext <- extent(UD) + 0.3 # set the extent for the plot
aa <-
quantile(UD,
probs = c(0.25, 0.75),
type = 8,
names = TRUE)
my.at <- c(aa[1], aa[2])
my.at <- round(my.at, 3)
maxval <- maxValue(UD)
tiff(
"C:/myworkingdirectory/maps/blablabla_UD_resolution_species_area_year_season.tiff",
res = 600,
compression = "lzw",
width = 15,
height = 15,
units = "cm"
)
levelplot(
UD,
xlab = "",
ylab = "",
xlim = c(ext[1], ext[2]),
ylim = c(ext[3], ext[4]),
margin = FALSE,
contour = FALSE,
col.regions = viridis(1000),
colorkey = list(at = seq(0, maxval)),
main = "A",
maxpixels = 2e5
) + latticeExtra::layer(sp.polygons(Land, fill = "grey50", col = NA)) + contourplot(
`UD`,
at = my.at[1],
labels = FALSE,
margin = FALSE,
lty = 2,
col = "orange",
pretty = TRUE
) + contourplot(
UD,
at = my.at[2],
labels = FALSE,
margin = FALSE,
lty = 2,
col = "red",
pretty = TRUE,
)
dev.off()
It is a common beginners mistake to use assign. Do not use it, it creates the type of trouble you are now facing. In stead, you can make lists and/or use a loop.
Also what you are asking is basic R stuff, but you are complicating the question with adding lots of irrelevant detail about setting the extent, and levelplot. It is better to learn about doing these basic things by removing the clutter and focus on a simple case first. That is also how you should write questions for this forum.
In essence you have a bunch of files you want to process. Below I show how you can loop over a vector of the names and then loop and do what you need to do in that loop.
library(raster)
rastfiles <- list.files(pattern = "tif$", full.names=TRUE)
outputfiles <- file.path("output/path", paste0("prefix_", basename(rastfiles)))
for (i in 1:length(rastfiles))
r <- raster(rastfiles[i])
png(outputfiles[i])
plot(r)
dev.off()
}
You can also first read all the files into a list
rastfiles <- list.files(pattern = "tif$", full.names=TRUE)
rlist <- lapply(rastfiles, raster)
names(rlist) <- gsub(".tif$", "", basename(rastfiles))
rastfiles <- list.files(pattern = "shp$", full.names=TRUE)
slist <- lapply(shpfiles, readOGR)
names(slist) <- gsub(".shp$", "", basename(shpfiles))
And perhaps create a vector of output filenames
outputtif <- file.path("output/dir", basename(rastfiles))
And then loop over the items in the list, or the output filenames

Skip empty panel using lattice package, R programming

I want to skip a empty panel using lattice package in R.
set.seed(1)
df1 <- data.frame("treatment" = c(rep("A",16),rep("B",16),rep("C",16)),
"disease_type" = c(rep("1",8),rep("2",8)),
"days_after_application" = rep(c(rep("10-24",4),rep("24-48",4)),6),
"severity" = rnorm(48, mean = 80, sd = 5))
df1[(df1$disease_type == "2" & df1$days_after_application == "24-48"),"severity"] <- NA
library(lattice)
figure1 <- bwplot(treatment~severity|days_after_application+disease_type,
data = df1,layout = c(2,2),
strip = strip.custom(strip.names = TRUE))
jpeg("figure1.jpeg")
print(figure1)
dev.off()
Here is what I get
My question is how I can remove/skip empty panel in the top right WITHOUT changing layout?
I have tried following code. However, it doesn't work.
figure2 <- bwplot(treatment~severity|days_after_application+disease_type,
data = df1,layout = c(2,2),
strip = strip.custom(strip.names = TRUE),
skip = c(FALSE,FALSE,FALSE,TRUE))
jpeg("figure2.jpeg")
print(figure2)
dev.off()
Here is what I got
I also tried following codes. But it is not what I want since I do want 2 levels strips.
df1[(df1$disease_type == "2" & df1$days_after_application == "24-48"),] <- NA
bwplot(treatment~severity|interaction(days_after_application,disease_type),
data = df1,layout = c(2,2),
strip = strip.custom(strip.names = TRUE))
Thank you!
Get help from a Professor in Temple University.
Here is his solution:
figure4 <- bwplot(treatment~severity|days_after_application+disease_type,
data = df1,layout = c(2,2),
strip = strip.custom(strip.names = TRUE),
skip = c(FALSE,FALSE,FALSE,TRUE),
scales=list(alternating=FALSE), ## keep x-scale on bottom
between=list(x=1, y=1)) ## space between panels
pdf("figure4%03d.pdf",onefile = FALSE) ## force two pages in file.
print(figure4)
dev.off()

How to take a sample from a large plot to show in knitr-PDF

I often create large plots in RStudio which I save to PDF but would also like to partly show in the PDF knitr report.
Is there a way to create the full object then cut a piece (ideally top left corner) and include that second picture in the PDF report?
as example, a pheatmap code that produces a plot with 56 cols and 100's of rows. I would like to show only the left-top-most 10col and 10 rows but if I sample the input data, I obviously get another plot due to the clustering being done on different data. Also, I would love a solution applicable to any plot types (not only pheatmap).
drows <- "euclidean"
dcols <- "euclidean"
clustmet <- "complete"
col.pal <- c("lightgrey","blue")
main.title <- paste("Variant (freq>", minfreq, "%) in all samples", sep="")
hm.parameters.maj <- list(hm.maj.data,
color = col.pal,
fontsize = 10,
cellwidth = 14,
cellheight = 14,
scale = "none",
treeheight_row = 200,
kmeans_k = NA,
show_rownames = T,
show_colnames = T,
main = main.title,
clustering_method = clustmet,
cluster_rows = TRUE,
cluster_cols = FALSE,
clustering_distance_rows = drows,
clustering_distance_cols = dcols,
legend=FALSE)
# To draw the heatmap on screen (comment-out if you run the script from terminal)
do.call("pheatmap", hm.parameters.maj)
# To draw to file (you may want to adapt the info(header(vcf))sizes)
outfile <- paste("major-variants_heatmap_(freq>", minfreq, ")_", drows, ".pdf", sep="")
do.call("pheatmap", c(hm.parameters.maj, filename=outfile, width=24, height=35))
Thanks in advance
Stephane

Saving multiply pdf plots r

I have made a loop for making multiply plots, however i have no way of saving them, my code looks like this:
#----------------------------------------------------------------------------------------#
# RING data: Mikkel
#----------------------------------------------------------------------------------------#
# Set working directory
setwd()
#### Read data & Converting factors ####
dat <- read.table("Complete RING.txt", header =TRUE)
str(dat)
dat$Vial <- as.factor(dat$Vial)
dat$Line <- as.factor(dat$Line)
dat$Fly <- as.factor(dat$Fly)
dat$Temp <- as.factor(dat$Temp)
str(dat)
datSUM <- summaryBy(X0.5_sec+X1_sec+X1.5_sec+X2_sec+X2.5_sec+X3_sec~Vial_nr+Concentration+Sex+Line+Vial+Temp,data=dat, FUN=sum)
fl<-levels(datSUM$Line)
colors = c("#e41a1c", "#377eb8", "#4daf4a", "#984ea3")
meltet <- melt(datSUM, id=c("Concentration","Sex","Line","Vial", "Temp", "Vial_nr"))
levels(meltet$variable) <- c('0,5 sec', '1 sec', '1,5 sec', '2 sec', '2,5 sec', '3 sec')
meltet20 <- subset(meltet, Line=="20")
meltet20$variable <- as.factor(meltet20$variable)
AllConcentrations <- levels(meltet20$Concentration)
for (i in AllConcentrations) {
meltet.i <- meltet20[meltet20$Concentration ==i,]
quartz()
print(dotplot(value~variable|Temp, group=Sex, data = meltet.i ,xlab="Time", ylab="Total height pr vial [mm above buttom]", main=paste('Line 20 concentration ', meltet.i$Concentration[1]),
key = list(points = list(col = colors[1:2], pch = c(1, 2)),
text = list(c("Female", "Male")),
space = "top"), col = colors, pch =c(1, 2))) }
I have tried with the quartz.save function, but that just overwrites the files. Im using a mac if that makes any difference.
When I want to save multiple plots in a loop I tend to do something like...
for(i in AllConcentrations){
meltet.i <- meltet20[meltet20$Concentration ==i,]
pdf(paste("my_filename", i, ".pdf", sep = ""))
dotplot(value~variable|Temp, group=Sex, data = meltet.i ,xlab="Time", ylab="Total height pr vial [mm above buttom]", main=paste('Line 20 concentration ', meltet.i$Concentration[1]),
key = list(points = list(col = colors[1:2], pch = c(1, 2)),
text = list(c("Female", "Male")),
space = "top"), col = colors, pch =c(1, 2))
dev.off()
}
This will create a pdf file for every level in AllConcentrations and save it in your working directory. It will paste together my_filename, the number of the iteration i, and then .pdf together to make each file unique. Of course, you will want to adjust height and width in the pdf function.

Lattice Package in R: Is it possible to develop an interactive "scatterplot/network"?

I am developing an interactive scatterplot so that when the user rolls over a data point, a label is displayed. However, I would also like to add edges between certain data points.
I am successful at developing the interactive scatterplot using several libraries, including grid, gridSVG, lattice, and adegraphics. Below is a MWE:
library(grid)
library(gridSVG)
library(lattice)
library(adegraphics)
x = rnorm(10)
y = rnorm(10)
dat = data.frame(label = letters[1:10], x, y)
customPanel2 <- function(x, y, ...) {
for (j in 1:nrow(dat)) {
grid.circle(x[j], y[j], r = unit(.5, "mm"),
default.unit = "native",
name = paste("point", j, sep = "."))
}
}
xyplot(y ~ x, panel = customPanel2, xlab = "x variable", ylab=NULL, scales=list(tck = c(1,0), y=list(at=NULL)))
for (i in 1:nrow(dat)) {
grid.text(as.character(dat$label)[i], x = 0.1, y = 0.01, just = c("left", "bottom"), name = paste("label", i, sep = "."), gp = gpar(fontface = "bold.italic"))
}
for (i in 1:nrow(dat)) {
grid.garnish(paste("point", i, sep = "."), onmouseover = paste('highlight("', i, '.1.1")', sep = ""), onmouseout = paste('dim("', i, '.1.1")', sep = ""))
grid.garnish(paste("label", i, sep = "."), visibility = "hidden")
}
grid.script(filename = "aqm.js", inline = TRUE)
grid.export("interactiveScat.svg")
The resulting .svg file accomplishes everything I am aiming for - except that I also wish to add certain non-interactive edges. I tried to do this by incorporating the adeg.panel.edges method from the adegraphics library after defining the edges and the coordinates to be mapped. So, basically my xplot(...) function from before is replaced with:
edges = matrix(c(1, 2, 3, 2, 4, 1, 3, 4), byrow = TRUE, ncol = 2)
coords <- matrix(c(x[1], y[1], x[2], y[2], x[3], y[3], x[4], y[4]), byrow = TRUE, ncol = 2)
xyplot(y ~ x, panel = function(customPanel2){adeg.panel.edges(edges, coords, lty = 1:4, cex = 5)}, xlab = "x variable", ylab=NULL, scales=list(tck = c(1,0), y=list(at=NULL)))
It seems that this simply erases the interactive scatterplot made from the original xyplot, and simply outputs the static edge and coordinate image.
I tried to follow the example as seen in (http://finzi.psych.upenn.edu/library/adegraphics/html/adeg.panel.nb.html). Specifically, this example:
edges <- matrix(c(1, 2, 3, 2, 4, 1, 3, 4), byrow = TRUE, ncol = 2)
coords <- matrix(c(0, 1, 1, 0, 0, -1, -1, 0), byrow = TRUE, ncol = 2)
xyplot(coords[,2] ~ coords[,1],
panel = function(...){adeg.panel.edges(edges, coords, lty = 1:4, cex = 5)})
I am a bit at a loss as to how to troubleshoot this problem, especially as I am mimicking the example code. Any suggestions are greatly appreciated!
If what you are trying to produce is a node-link diagram of a network an alternate solution is to coerce your data into a network object and use the ndtv package to generate svg/htmlwidget interactive plots for your network. The ndtv package is designed for dynamic networks, but will generate interactive plots for static nets as well.
library(ndtv)
data(emon) # load a list of example networks
render.d3movie(emon[[5]]) # render network 5 in the browser
Much more detail is in the tutorial http://statnet.csde.washington.edu/workshops/SUNBELT/current/ndtv/ndtv-d3_vignette.html
However, this does not use grid/lattice graphics at all

Resources