I am executing some R scripts with a source() command and then flushing the console. The only thing that I want visible in the console is some text with a progress report of the script, after that some progress bars are displayed, all the rest of the code is hidden. I am printing my progress report to the console by manually adding the text using the cat() function as below.
cat("\014")
cat(" =====================================\n")
cat(" ========== PROGRESS REPORT ==========\n")
cat(" =====================================\n")
cat("\n")
# progress bar implementation
What I was wondering: Is there a way to center the text automatically in the middle of the console so that it adjusts dynamically when you resize the window size of the console? I am looking for a way that works both in R Studio and also baseR in Windows and Mac OS X.
You could try something like this. This may or may not be exactly centered, it depends on the current console width (which is floored if an odd number occurs in the calculation of p).
centerText <- function() {
width <- getOption("width")
out <- "=======================================\n"
mid <- "=========== PROGRESS REPORT ===========\n"
ws <- rep(" ", floor((width - nchar(out))/2))
cat(ws, out, ws, mid, ws, out, sep = "")
}
centerText()
It works in RStudio, but I'm not sure if it works in the normal R console. Might need some tweaking.
Related
grDevices::dev.size() programmatically provides the size of the Viewer pane in RStudio.
Is there a similar command (or maybe even a hack) for programmatically obtaining the size of the Zoom window? A brief search of the rstudioapi commands doesn't seem to offer any leads.
It has been a long time since I've been stuck with a similar problem. Have you found the answer?
I went with this solution:
Start with window
}
x11() # open new window
boxplot(rnorm(100)) # wrtie some good box full of normal values.
#Plot it! You will see it on the new screen.
#Now, let's make this loop, and everything will appear.
while(TRUE){
cdev <- grDevices::dev.size("cm")
Sys.sleep(0.5)
cat("Width (cm):", cdev[1], "High (cm):", cdev[2], "\r")
cat("Press escape to break it.")
}
#Change the new windows number size, and those new numbers will flow.
I am working on a little interactive shell-like tool in R that uses readline to prompt stdin, like this:
console <- function(){
while(nchar(input <- readline(">>> "))) {
message("You typed: ", input)
}
}
It works but the only thing that bothers me is that lines entered this way do not get pushed upon the history stack. Pressing the up-arrow in R gives the last R command that was entered before starting the console.
Is there any way I can manually push the input lines upon the history stack, such that pressing the up-arrow will show the latest line entered in the console function?
I use this in rite to add commands to the command history. In essence, you can just savehistory and loadhistory from a local file. I do:
tmphistory <- tempfile()
savehistory(tmphistory)
histcon <- file(tmphistory, open="a")
writeLines(code, histcon)
close(histcon)
loadhistory(tmphistory)
unlink(tmphistory)
Note: Mac doesn't use history in the same way as other OS's, so be careful with this.
I just encountered something baffling (at least to me) and hope wiser members can shed some light.
I used RStudio 0.98.490 on Windows XP to save a plot to PNG. The filename was created using strwrap(sprintf()). I habitually use longer (i.e. more informative) filenames, and I guess I was probably over-enthusiastic this time, which is why this issue surfaced.
I noticed that when the width of the RStudio console is shorter than the length of the filename during run-time, the latter gets truncated and the file created does not have the .png extension. I experimented and dragged the width of RStudio console to longer than the filename - the problem disappears.
My question: why does this happen? More importantly, can I resolve this truncation without changes to my filename? I am a newbie to R and I can't see why 2 seemingly unrelated items should interact.
Truncation shown below:
> writeLines( paste0(FName, " generated") ) # Write to Console
aaaaaa aaaaaaaaaaaaaabcdef ghijk lmnopqrstuvaaaaaa aaaaaaaaaaaaa213424534aaaaaa generated
aaaaaaaaaaaaa.png generated
>
Sample code is attached below:
astring <- "aaaaaa aaaaaaaaaaaaa"
FName <- strwrap( sprintf("%sabcdef ghijk lmnopqrstuv%s213424534%s.png",
astring, astring, astring) ) # simulate long filename
png( filename = FName)
a <- rnorm(100)
b <- rnorm(100)*2
plot(b,a)
dev.off()
writeLines( paste0(FName, " generated") ) # Write to Console
The closest resource I found was https://stackoverflow.com/questions/6104448/preserving-long-comments-in-console-output-not-falling-victim-to-truncat but the problem faced by the author appeared slightly different.
I would appreciate very much if someone can enlighten. Thanks!
EDIT: Thanks to #jlhoward, I looked up strwrap() and found the width parameter. By assigning '255' (or any big integer), the problem is resolved.
Why are you using strwrap(...)?
As the documentation explains, strwrap(...) parses your input into words, and then wraps (by inserting "\n") based on a width parameter. The default for this parameter is getOption("width"), which is based on the console width. Try typing
getOption("width")
then shrink or expand your console window and do it again.
If you just use sprintf(...) to generate your filename, you don't have this problem.
I have written a function that creates a barplot. I would like to save this plot as a pdf as well as display it on my screen (x11) when applying this function. The code looks like this.
create.barplots <- function(vec)
{
x11() # opens the window
### Here is a code that creates a barplot and works perfectly
### but irrelevant for my question
dev.copy(pdf("barplots.table.2.pdf")) # is supposed to copy the plot in pdf
# under the name "barplots.table.2.pdf"
dev.off() # is supposed to close the pdf device
}
This creates the following error: 'device' should be a function
When I modify the code to:
create.barplots <- function(vec)
{
x11()
### Here is a code that creates a barplot and works perfectly
### but irrelevant for my question
dev.copy(pdf) # This is the only difference to the code above
dev.off()
}
R displays the plot and creates a file called Rplots.pdf. This is a problem because of several reasons.
I also tried to open the devices the other way around. First open the pdf device, than copy the content of the pdf device into the x11 device, than set the pdf device as active and than close the pdf device. The code here looks like this:
create.barplots <- function(vec)
{
pdf("barplots.table.2.pdf") # open the pdf device
### Here is a code that creates a barplot and works perfectly
### but irrelevant for my question
dev.copy(x11) # copy the content of the pdf device into the x11 device
dev.set(which = 2) # set the pdf device as actice
dev.off() # close the pdf device
}
The problem here is that the wondow that is supposed to display the plot is empty!
To sum up, I have two questions:
1) How to save a plot as pdf and display it in x11 simultaneously? And
2) How to save the plot not in the working directory somewhere else?
EDIT
The solutions above work great. But I still do not understand why
pdf("barplots.table.2")
barplot(something)
dev.copy(x11)
displays an empty grey window instead of copying the content of the pdf device in the window device! I also tried
pdf("barplots.table.2")
barplot(something)
dev.copy(window)
In which I failed as well...
How about:
create.barplots <- function(...) {
x11()
plot.barplots(...) # create the barplot
dev.copy2pdf(file = "path/to/barplots.table.2.pdf")
}
You can easily add arguments for pdf in the dev.copy call, like this:
create.barplots <- function(vec,dir,file)
{
windows()
plot(vec)
dev.copy(pdf,file=paste(dir,file,sep="/")
dev.off()
}
dev.copy() has a ... argument to pass arguments to the pdf function, see also ?dev.copy. Alternatively you can use dev.copy2pdf , as Max told you. I'd also advise you to use windows() instead of x11(), otherwise you might have trouble with the font families. The defaults for x11 and pdf don't always match.
To save a file in another directory, just add the full directory (eg with paste, like in the function above)
As I mentioned in a previous post, you may consider my knitr package; if you use it in an interactive R session, you will be able to see the plots in a window and save them to pdf without any hacks (it is the default behavior). I still need a lot of efforts on the documentation and demos, but it should be able to work with an Rnw document. The main reason that you can both see the plots and save them in knitr is, knitr is very different with Sweave in design -- the graphical device is opened after the code is evaluated, so your plots will not be hidden in an off-screen device. Again, I need to warn you that it is highly experimental at the moment.
Following works nicely for me when called from inside functions. Call it after the plot code:
pdf2 <- function (file = "plot.pdf", w = 10, h = 7.07, openPDF = FALSE)
{
dev.copy2pdf(file = file, width = w, height = h, out.type = "pdf")
if(openPDF) browseURL(file)
}
NB. openPDF may only work in Windows with full (not relative) file path.
Based on the answer by Max Gasner, I wrote this helper function which allows to quickly switch from displaying and not. The argument x is a plot object or the function that does the drawing.
savepdf<-function(x, file, display=TRUE) {
if (display){
x;
dev.copy2pdf(file=file)
}
else {
pdf(file=file)
x;
dev.off()
}
}
Example:
savepdf(plot(c(1,2,3)), file="123.pdf", display=F)
whenever I run some R code with Sweave, it displays the terminal arrows (">") in the document. This is fine for session inputs, but sometimes I'd like to include custom functions. When arrows show up in the document, it is more difficult to copy and paste important snippets of code. Is there a quick way to do this?
I know I can run the code while suppressing the output all together, and then copy that code into a \Verbatim, but that requires extra typing.
Thanks
dumbo <- function(x)
2*x
instead of
> dumbo <- function(x)
> 2*x
Just add this to the top of the first chunk:
options(prompt=" ",continue=" ")
You can get back any moment with:
options(prompt="> ",continue="+ ")
options(prompt=" ")
You can set it back at the end.
options(prompt="> ")
This is off by default in knitr, the "next generation Sweave". Other nice features include syntax coloring and PGF integration.
Sweave code of average complexity needs only minor if any adaptions to run with knitr.