I have multiple files to read and also do heatmap after which the outputs will be saved. Somehow, there is a problem(s) with my code below and I can't figure out why it is not working. Files: mxn.dat, scu.dat, emun.dat, ser.dat
files <- list.files(pattern=".dat")
for (i in length(files)){
data <-read.table(files[i],row.names=1,header=T,sep='\t')
for in length(files){
png('i.png')
pheatmap(t(data[i]), cellwidth = 32, cellheight = 14, fontsize = 5, show_colnames = T, cluster_cols = FALSE)
dev.off()
}
}
Any help will be appreciated to get the code working.
Thanks
Rob
Not a reproducible example so I have no way to test if this will work (and somehow I think that this is too localised to be useful to future visitors), but perhaps try this...
files <- list.files(pattern=".dat")
for (i in 1:length(files)){
data <-read.table( files[i],row.names=1,header=T,sep='\t')
png( paste0( i , '.png' ) )
pheatmap( t( data ), cellwidth = 32, cellheight = 14, fontsize = 5, show_colnames = T, cluster_cols = FALSE)
dev.off()
}
Variation of SimonO101's solution:
files <- list.files(pattern=".dat")
for( f in files )
{
data <-read.table( f, row.names = TRUE, header = TRUE, sep = '\t' )
png( gsub( "pdf", "png", f ) )
pheatmap( t( data ), cellwidth = 32, cellheight = 14, fontsize = 5, show_colnames = T, cluster_cols = FALSE)
dev.off()
}
Easier to read (I believe) and has the advantage (?) of preserving the original file names, only changing the extension.
Related
I am having an issue with a TIFF files saving, but the graph does not have any content in it. This is specifically happening with an if statement.
if (RMCAv_Graph == T){
Save_Path = file.path(Sub_Folder_Path, "RMCAv.tiff")
tiff(file = Save_Path, units = "in", width = 5, height = 5, res = 600)
RMCAv_Plot
dev.off()
}
I tried to put it into the conditional statement and without the graph. When I put the if statement in the graph, it will not populate as expected.
If you are writing to file inside of a conditional statement, you need to directly tell it to print.
if (RMCAv_Graph == T){
Save_Path = file.path(Sub_Folder_Path, "RMCAv.tiff")
tiff(file = Save_Path, units = "in", width = 5, height = 5, res = 600)
RMCAv_Plot %>% print()
dev.off()
}
or without the pipe:
if (RMCAv_Graph == T){
Save_Path = file.path(Sub_Folder_Path, "RMCAv.tiff")
tiff(file = Save_Path, units = "in", width = 5, height = 5, res = 600)
print(RMCAv_Plot)
dev.off()
}
library(pdftools)
sapply(list, function(x)
pdf_convert(x, format = "png", pages = NULL, filenames = NULL, dpi = 300, opw = "", upw = "", verbose = TRUE))
I know that pages = NULL means for all pages. I am having trouble how to do only odd pages. Does anyone know what I should put to do only odd pages? Thank you in advance.
The pages argument accepts a vector of the page numbers you want. You could make a sequence of the odd page numbers with the help of the total available in pdftools::pdf_info().
sapply(list, function(x)
pdf_convert(x,
format = "png",
pages = seq(from = 1, to = pdf_info(x)$pages, by = 2),
filenames = NULL,
dpi = 300,
opw = "",
upw = "",
verbose = TRUE))
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
I have list of data and list of plots which I want two write to xlsx file (each element to separate sheet). Example data:
require(ggplot2)
require(data.table)
n <- 10
N <- 100
dtList <- lapply(1:n, function(x) data.table(sample(1e6, N), 1:N))
names(dtList) <- 1:n
plots <- lapply(dtList, function(x) ggplot(x, aes(y = V1, x = V2)) + geom_line())
Currently I use openxlsx, but it is quite slow for multiple plots:
require(openxlsx)
wb <- createWorkbook()
modifyBaseFont(wb, fontSize = 10)
writeXlsx <- function(x, sName) {
addWorksheet(wb, sName, gridLines = FALSE)
writeData(wb, sName, x = x, xy = c(1, 1))
print(plots[[sName]])
insertPlot(wb, sName, width = 19, height = 9, dpi = 200, units = "cm",
startRow = 2, startCol = 5)
}
system.time(
sapply(seq_along(dtList), function(x) {
writeXlsx(dtList[[x]], names(dtList)[[x]])
})
) # ~ 17.00 sek
openXL(wb)
How could I increase speed of this? Is there a better package to accomplish this?
One options is to use simpler graphics. For example, changing plots to base graphics, like:
plots <- lapply(dtList, function(x) plot(x$V2, x$V1, type = 'l'))
reduces the xlsx creation time to ~0.72 seconds vs ~7.78 seconds (original code works now faster than before), that is around 10 times faster.
When ggplot graphics are needed, I modified insertPlot function to accept this type of object and save it to file without needing to print in R session (using ggsave):
insertggPlot <- function(wb, sheet, width = 6, height = 4, xy = NULL,
startRow = 1, startCol = 1, fileType = "png",
units = "in", dpi = 300, PLOT) {
od <- getOption("OutDec")
options(OutDec = ".")
on.exit(expr = options(OutDec = od), add = TRUE)
if (!"Workbook" %in% class(wb)) stop("First argument must be a Workbook.")
if (!is.null(xy)) {
startCol <- xy[[1]]
startRow <- xy[[2]]
}
fileType <- tolower(fileType)
units <- tolower(units)
if (fileType == "jpg") fileType = "jpeg"
if (!fileType %in% c("png", "jpeg", "tiff", "bmp"))
stop("Invalid file type.\nfileType must be one of: png, jpeg, tiff, bmp")
if (!units %in% c("cm", "in", "px"))
stop("Invalid units.\nunits must be one of: cm, in, px")
fileName <- tempfile(pattern = "figureImage",
fileext = paste0(".", fileType))
ggsave(plot = PLOT, filename = fileName, width = width, height = height,
units = units, dpi = dpi)
insertImage(wb = wb, sheet = sheet, file = fileName, width = width,
height = height, startRow = startRow, startCol = startCol,
units = units, dpi = dpi)
}
Using this, reduces time to ~2 sek.
I want to write a set of randomly generated numbers to a text file with fixed format. But for some reasons, write.fwf only wrote the 1st column right, all other columns got one extra digit. How can I fix it? Thanks!
set.seed(1899)
library(sensitivity)
library(randtoolbox)
par_lower <- c( 0.12, 0.13, 0.038, 0.017)
par_upper <- c(12.00, 13.00, 3.800, 1.700)
sample_size <- 5
lim_para8 <- c(par_lower[1], par_upper[1])
lim_para9 <- c(par_lower[2], par_upper[2])
lim_parb8 <- c(par_lower[3], par_upper[3])
lim_parb9 <- c(par_lower[4], par_upper[4])
par_rand <- parameterSets(par.ranges = list(lim_para8, lim_para9,
lim_parb8, lim_parb9),
samples = sample_size, method = "sobol")
par_rand
# write to file
library(gdata)
file2write <- paste("par.txt", sep = "")
write.fwf(par_rand, file = file2write, width = c(10, 10, 10, 10), colnames = FALSE)
The results:
6.060 6.56500 1.91900 0.858500
9.030 3.34750 2.85950 0.437750
3.090 9.78250 0.97850 1.279250
4.575 4.95625 2.38925 0.227375
10.515 11.39125 0.50825 1.068875
If I changed to
write.fwf(par_rand, file = file2write, width = c(10, 9, 9, 9),
colnames = FALSE, quote = FALSE, rownames = FALSE)
I got this error
Error in write.fwf(par_rand, file = file2write, width = c(10, 9, 9, 9), :
'width' (9) was too small for columns: V4
'width' should be at least (10)
Please try the code below, it works for me. I tested with several formats and all worked. Both code segments return a fixed format file with width 4 x 10.
This of course implies that setting sep in the definition of file2write does not work for getting the desired output with write.fwf
write.fwf(par_rand, file = "par2.txt", width = c(10, 10, 10, 10), colnames = FALSE, sep = "")
write.fwf(par_rand, file = file2write, width = c(10, 10, 10, 10), colnames = FALSE, sep = "")
The following generates the same but with 1x10 and 3x9, as I think you wanted
write.fwf(par_rand, file = "par3.txt", width = c(10, 9, 9, 9), colnames = FALSE, sep = "")
Please let me know whether this is what you wanted.