sink vs console output---what is the opposite of message()? - r

I am trying to take full control of output to both the console and the (split) sink file. For one, I want certain output to be colored on the [ansi] console but not clutter up my Rout file.
I know of two basic commands:
cat() outputs to both the console and the sink file.
message() outputs only to the console (via file stderr), but not to the sink file.
I start with
messageln <- function(...) {
boldblue <- "\033[34;1m"; ansioff <- "\033[0m"
if (interactive()) message(boldblue) # fails. stderr dest overrides
cat(..., sep="")
if (interactive()) message(ansioff) # fails. stderr dest overrides
}
Problem 1: the ansi terminal command is emitted and interpreted by my console only if I use cat instead of message. this is presumably because message emits its own ansi-off to turn off coloring.
Problem 2: is there an opposite to message() that outputs a string only to the sink file but not to the console?

Related

R sink() message and output to same file - sanity check

I'm using R's sink() function to capture errors, warnings, messages and console output into a single text file.
I'm wondering if simultaneously sinking both message and output types to a single open file is bad to do?
I capture all of the above into a single file, but I must open a file handle to allow both sink types to be captured. The following code illustrates using the file handle approach:
message_filename = 'script_messages.txt'
try(message_file <- file(message_filename, open="at")) # open file for appending in text mode
sink(message_file, type="message")
sink(message_file, type="output")
cat("\n\n")
message(format(Sys.time(), "%a %b %d %Y %X TZ(%z)"), appendLF = TRUE)
# next line produces messages since file doesn't exist
try(source("import_file.R"), silent = TRUE)
# Save and close writing errors, warnings, messages, and console output to a file
sink(type="output")
sink(type="message")
close(message_file)
If I don't open a file handle, then the sink 'output' type messages are the only ones captured in the text file.
The documentation on sink {base} has some key info in the first half of the Details section, but I'm not fluent enough to be sure I've implemented it properly.
I believe it's to do with the global option for warn. The default is warn=0 which means "warnings are stored until the top–level function returns". In other words, when you source("script.R"), R stores up the warnings and prints them once your script has finished, i.e. after you've run sink(type="output"); sink(type="message"); close(message_file).
To change this you can call options(warn=1) before you source your script, this will print warnings as they occur and will therefore be caught by your sink. This only needs to be run once per session.

Suppress Messages from zip in R

I want to suppress the messages as outputted by the zip command in r but I fail to find the right command to do so.
Background, as I use the zip-function within a function, I don't want the user to see all information about all the files (roughly 5.000, which clutters the console).
Here is what I have tried so far, but all functions foo show either adding: hw.txt (stored 0%) or updating: hw.txt (stored 0%)
# create a small file
writeLines("hello world", "hw.txt")
# use the original command
zip("zip.zip", "hw.txt")
# try different options of capturing/suppressing output!
# assignment
foo1 <- function() a <- zip("zip.zip", "hw.txt")
foo1()
# capture.output
foo2 <- function() a <- capture.output(zip("zip.zip", "hw.txt"))
foo2()
# suppressMessages
foo3 <- function() suppressMessages(zip("zip.zip", "hw.txt"))
foo3()
# invisible
foo4 <- function() invisible(zip("zip.zip", "hw.txt"))
foo4()
# sink
foo5 <- function() {
sink(tempfile())
zip("zip.zip", "hw.txt")
sink()
}
foo5()
Are there any other options to suppress the output of zip?
The answer will depend on the system that the code is used on. On my Windows system, I can use
zip("zip.zip", "hw.txt", flags="-q")
and it suppresses messages, but it depends on what your system uses to handle zip files. Since the message is coming from the zip program, you must signal it not to output messages.

Error Handling and logging in R

I have written a function in R to print any message both to log file and console. But if there is any unexpected error while running the code, then error is displayed only to console. Is there any way to write error message to both console and log file? Here is the function..
log_con <- file("Text1.txt", open="a")
loggerfn<-function(Message,LogConnection=log_con){
cat(Message, file = LogConnection)
cat(Message)
}
Here is the sample code to...
for (i in 1:10)
{
loggerfn("loop begins\n",log_con)
a <- rnorm(n = 100, mean = i, sd = 5)
loggerfn(mean(a),log_con)
loggerfn("loop Completed\n",log_con)
if(i==8){
sdfs
}
}
In above code I have intentionally introduced error by providing undefined object sdfd.Below provided Error message is shown only in console, is there any way to write error message to both console and logfile?
Error: object 'sdfs' not found
use sink() to divert messages as well as warnings to a file. The trick is to set the argument type="message"
refer http://www.statmethods.net/interface/io.html
and Output error/warning log (txt file) when running R script under command line
https://stat.ethz.ch/R-manual/R-devel/library/base/html/sink.html
The sink( ) function defines the direction of the output.
Description
sink diverts R output to a connection (and stops such diversions).
sink.number()
reports how many diversions are in use.
sink.number(type = "message") reports the number of the connection currently being used for error messages.
Usage
sink(file = NULL, append = FALSE, type = c("output", "message"),
split = FALSE)
sink.number(type = c("output", "message"))
direct output to a file
sink("myfile", append=FALSE, split=FALSE)
return output to the terminal
sink()
The append option controls whether output overwrites or adds to a file. The split option determines if output is also sent to the screen as well as the output file.
Here are some examples of the sink() function.
output directed to output.txt in c:\projects directory.
output overwrites existing file. no output to terminal.
sink("c:/projects/output.txt")
output directed to myfile.txt in cwd. output is appended
to existing file. output also send to terminal.
sink("myfile.txt", append=TRUE, split=TRUE)
When redirecting output, use the cat( ) function to annotate the output.

Can I declare file for output to console?

I have a routine to write (writeLines with sprintf) to output some values to the console.
I was asked to do the same output to a txt file.
What I have now is to duplicate the first set of "writeLine"s and change them to a write(..., file)
I am unable to find if I can declare a file to the console. What I am thinking is to have a function to do that and pass a parameter (file) and then just one set of statements for the write and call
diskfile <- file("results.txt", "w")
printresults("console") # This is the part I don't know how
printresults(diskfile)
If I do the printresults to the file, I can read from it and present to the console. I am using:
cat(readlines, ...)
This works fine but I preferr to have the function solution.
Is there a way to do that?
Thanks for your time,
EDIT>>> More specific
Can I do write(sprintf(...), CONSOLE)?
Would sink() (a favourite of mine) do the trick?
sink("file.txt", append = FALSE, split = TRUE)
print("Hello world")
sink()
With split = TRUE the output is passed to the console and the text file simulataneously, and the second call to sink() reverts output back to the console.
Both the console and file.txt print
"Hello world"

Make R wait for console input?

Is there a way to make R wait for console input before continuing?
Let's say I source two scripts like this in a main script called run.R:
# some more R Code here
source("script1.R")
source("script2.R")
# some more R Code there
Script1 contains some readLine statement that asks the user for a username.
Unfortunately if I just run the entire run.R file R doesn't wait for the username to be entered. It starts script2.R before the username is entered which leads to an error because the 2nd script needs the username.
I have an ugly workaround for this using R Studio's .rs.askForPassword which actually waits for the the input, but covers the password. Which is cool for passwords, but not so much for usernames. Plus it's an RStudio feature, not R.
readline can only be used in interactive sessions. In non-interactive use of readline the result is an empty string. On the help page of ?interactive you find the following about interactive sessions:
GUI consoles will arrange to start R in an interactive session. When R
is run in a terminal (via Rterm.exe on Windows), it assumes that it is
interactive if ‘stdin’ is connected to a (pseudo-)terminal and not if
‘stdin’ is redirected to a file or pipe. Command-line options
--interactive (Unix) and --ess (Windows, Rterm.exe) override the default assumption.
Try scan function.
This is test.R file:
y <- 2
cat('y=',y)
cat("\nEnter username")
x <- scan(what=character(),nmax=1,quiet=TRUE)
"ala ma kota"
y <- 2*2
cat('y=',y)
cat('\nx=',x)
and then I run this:
> source("test.R")
y= 2
Enter username
1: login
y= 4
x= login
--edit--
To read only one character quietly run this:
> x <- scan(what=character(),nmax=1,quiet=TRUE)
1: username
> x
[1] "username"
what sets the type, nmax sets the maximal numbers of elements to read and quiet determine if print a line, saying how many items have been read.
Why not putting
source("script2.R")
into the file script1.R?

Resources