Why does Rstudio print an extra line when printing text with cat? - r

Consider this code:
{
cat("hello")
Sys.sleep(1)
cat("\rhi there!")
}
In both the terminal and Rstudio we see the word 'hello' followed by 'hi there!' one second later but the terminal ends with hi there!> while Rstudio ends on a new line with >. Is there any way to get both systems to agree on how they print things using some option? Or is this something special that Rstudio does?

Try with
{
cat("hello")
Sys.sleep(1)
cat("\rhi there!\n")
}

Related

Rscript and user prompts

Have a fully working R-script. When executing it from Rscript it doesn't stop to accept user input however.
The user input is some readline statements. The cat statements prompting for input works as intended. Have I missed something?
I execute 'Rscript scriptfile.R' from terminal on macOS.
You can create a function typeline() to read an input line and then use the result for your next commands. It will wait for your input text either you run your code in Rstudio or in terminal:
typeline <- function(msg="Enter text: ") {
if (interactive() ) {
txt <- readline(msg)
} else {
cat(msg);
txt <- readLines("stdin",n=1);
}
return(txt)
}
txt=typeline("your message: ")
print(txt)
Managed to get it to work by changing readline to readLines as mentioned in the post suggested by meenaparam. The downside with this method is that ithe script only works in batch mode, running it in Rstudio makes it hang. Would be good to know a general way to capture keyboard input i.e that works both in interactive and batch mode.
Use this
cat("What's your name? ")
name <- readLines(file("stdin"),1)
cat("What's your age? ")
age <- readLines(file("stdin"),1)
print(name)
print(age)

Python Interpreting things from document

So, I am essentially just dreaming up ideas right now.
I was wondering if it was possible to make a python program that can read a document, take a line from the document, make an if/else statement with it (Like if the text on that line is equal to Hello, than say hello back), and then continue onto the next line. I have already kind of done this in a shell fashion but I want to see if it is possible to have python read the line of a document, interpret it, display something, and move on to the next line of the document.
(I am prepared for this post to get tons of -1's for not knowing how to program a lot of python, and probably just not being clear enough. So before you -1, just add a comment saying what you need me to be clear about.)
The version of python of my choice would be 2.5.
Since you don't know any Python, try this:
with open("file.txt") as f:
for line in f:
if line.strip() == "Hello":
print "Hello back"
or without the exception-safe clause:
for line in open("file.txt"):
if line.strip() == "Hello":
print "Hello back"
the strip() removes the ending newline \n from the line
That is actually a very simple task in Python:
file = open("file.txt") # open the file
while True:
word = file.readline() # read a line from the file
print word # print it to the console
if word == "": # if out of words...
file.close() # ...close the file
break # and break from while loop and exit program

Emacs ESS Mode TAB stops indenting

I'm using Emacs 24 on Windows to write some R code. Up until about 30 minutes ago, whenever I would write a new function, ESS would automatically indent the lines following the function declaration and pressing the tab key on a new blank line would jump me to the appropriately indented starting position inside the declaration.
EG:
foo <- function() {
first line started here
second line here. .etc
}
Now, it is hard wrapping everything to the left, and not responding by automatically indenting after the function declaration or when I hit the tab key.
foo <- function() {
first line
second line
}
I've googled, but my google-fu is failing me on this. Anyone know how to restore default tab behavior to ESS in Emacs?
just for the record. Whenever such things happens, select the whole buffer C-x h and press C-M-\ to indent the whole region. This will show unambiguously the syntax error.
Try to add a space after "#".
I don't think ESS-mode handles # as a comment unless you have space after it.
I just came across the same problem you describe.
None of the above seemed to work, but I narrowed it down to using a carriage return and then an open parenthesis inside a string, like so:
### indent ( <tab> ) working fine up to here
s1 <- "string
(then this in brackets)"
### now indent does nothing!
The fact that it's balanced later doesn't help. I think EMACS reads this as opening a new expression/ block in spite of the fact that it occurs in a quoted string. This seems to apply also to expression openers { and [. It only seems to happen when the 'open expression' symbol appears at the start of the line...
In my case the string was part of a plot label, so the solution was to use \n instead.

Overwrite current output in the R console

I have been playing around with the R function txtProgressBar(). How can I hijack the function's ability to overwrite the current output in the console?
i.e. the progress bar updates like this:
> some R function
============
becomes
> some R function
========================
NOT
> some R function
============
========================
For example, how do I write function that will display the current time in the console:
> some R function
13:01
becomes
> some R function
13:02
NOT
> some R function
13:01
13:01
13:01
13:01
13:02
13:02
13:02
13:02
Instead of "\b\b\b\b" you can just use "\r" to go to the beginning of the line and overwrite everything on the line (make sure to still use cat and don't put in a line feed).
Though if you want to display progress it might be better to use winProgressBar (windows only) or tkProgressBar (tcltk package, all platforms) which can be updated with a label in addition to the progress bar.
On windows you can also use the setWindowTitle or setStatusBar functions to put that type of information into the top or bottom of the larger window.
This program seems to work:
while (1) {
cat('\b\b\b\b\b\b',format(Sys.time(),'%H:%M'))
flush.console()
}
Are there any reasons this might be a bad idea?
/edit: even better (thanks #Greg Snow):
while (1) {
cat('\r',format(Sys.time(),'%H:%M:%S'))
flush.console()
}
Sure you can:
while(1) {
cat("\b\b\b\b\b\b\b\b",format(Sys.time(), "%H:%M:%S"),sep="")
}
In case you want to use the function message to print something, you can set its parameter appendLF to FALSE to avoid it printing a new line and then the use the carriage return ('\r') character to return to the start of the line, for example:
for (i in 1:5) {
message('\r', i, appendLF = FALSE)
}
I do not think overwriting is possible on the console. There is no backspace escape sequence. The progress bar can be drawn because the cat function will not emit a cr unless told to do so.
Edit:
I was wrong. The backspace character is recognized:
for (i in 1:1000) {
cat(as.character(Sys.time()))
flush.console()
for(i in 1:19) {cat("\8")} }

Multiline Comment Workarounds?

I (sort of) already know the answer to this question. But I figured it is one that gets asked so frequently on the R Users list, that there should be one solid good answer. To the best of my knowledge there is no multiline comment functionality in R. So, does anyone have any good workarounds?
While quite a bit of work in R usually involves interactive sessions (which casts doubt on the need for multiline comments), there are times when I've had to send scripts to colleagues and classmates, much of which involves nontrivial blocks of code. And for people coming from other languages it is a fairly natural question.
In the past I've used quotes. Since strings support linebreaks, running an R script with
"
Here's my multiline comment.
"
a <- 10
rocknroll.lm <- lm(blah blah blah)
...
works fine. Does anyone have a better solution?
You can do this easily in RStudio:
select the code and click CTR+SHIFT+C
to comment/uncomment code.
This does come up on the mailing list fairly regularly, see for example this recent thread on r-help. The consensus answer usually is the one shown above: that given that the language has no direct support, you have to either
work with an editor that has region-to-comment commands, and most advanced R editors do
use the if (FALSE) constructs suggested earlier but note that it still requires complete parsing and must hence be syntactically correct
A neat trick for RStudio I've just discovered is to use #' as this creates an self-expanding comment section (when you return to new line from such a line or insert new lines into such a section it is automatically comment).
[Update] Based on comments.
# An empty function for Comments
Comment <- function(`#Comments`) {invisible()}
#### Comments ####
Comment( `
# Put anything in here except back-ticks.
api_idea <- function() {
return TRUE
}
# Just to show api_idea isn't really there...
print( api_idea )
`)
####
#### Code. ####
foo <- function() {
print( "The above did not evaluate!")
}
foo()
[Original Answer]
Here's another way... check out the pic at the bottom. Cut and paste the code block into RStudio.
Multiline comments that make using an IDE more effective are a "Good Thing", most IDEs or simple editors don't have highlighting of text within simple commented -out blocks; though some authors have taken the time to ensure parsing within here-strings. With R we don't have multi-line comments or here-strings either, but using invisible expressions in RStudio gives all that goodness.
As long as there aren't any backticks in the section desired to be used for a multiline comments, here-strings, or non-executed comment blocks then this might be something worth-while.
#### Intro Notes & Comments ####
invisible( expression( `
{ <= put the brace here to reset the auto indenting...
Base <- function()
{ <^~~~~~~~~~~~~~~~ Use the function as a header and nesting marker for the comments
that show up in the jump-menu.
--->8---
}
External <- function()
{
If we used a function similar to:
api_idea <- function() {
some_api_example <- function( nested ) {
stopifnot( some required check here )
}
print("Cut and paste this into RStudio to see the code-chunk quick-jump structure.")
return converted object
}
#### Code. ####
^~~~~~~~~~~~~~~~~~~~~~~~~~ <= Notice that this comment section isnt in the jump menu!
Putting an apostrophe in isn't causes RStudio to parse as text
and needs to be matched prior to nested structure working again.
api_idea2 <- function() {
} # That isn't in the jump-menu, but the one below is...
api_idea3 <- function() {
}
}
# Just to show api_idea isn't really there...
print( api_idea )
}`) )
####
#### Code. ####
foo <- function() {
print( "The above did not evaluate and cause an error!")
}
foo()
## [1] "The above did not evaluate and cause an error!"
And here's the pic...
I can think of two options. The first option is to use an editor that allows to block comment and uncomment (eg. Eclipse). The second option is to use an if statement. But that will only allow you to 'comment' correct R syntax. Hence a good editor is the prefered workaround.
if(FALSE){
#everything in this case is not executed
}
If find it incredible that any language would not cater for this.
This is probably the cleanest workaround:
anything="
first comment line
second comment line
"
Apart from using the overkilled way to comment multi-line codes just by installing RStudio, you can use Notepad++ as it supports the syntax highlighting of R
(Select multi-lines) -> Edit -> Comment/Uncomment -> Toggle Block Comment
Note that you need to save the code as a .R source first (highlighted in red)
I use vim to edit the R script.
Let's say the R script is test.R, containing say "Line 1", "Line 2", and "Line 3" on 3 separate lines.
I open test.R on the command line with Vim by typing "vim test.R".
Then I go to the 1st line I want to comment out, type "Control-V", down arrow to the last line I want to comment out, type a capital I i.e. "I" for insert, type "# ", and then hit the Escape key to add "# " to every line that I selected by arrowing down. Save the file in Vim and then exit Vim by typing ":wq". Changes should show up in Rstudio.
To delete the comments in Vim, start at the first line on top of the character "#" you want to delete, again do "Control-V", and arrow down to the last line you want to delete a "#" from. Then type "dd". The "#" signs should be deleted.
There's seconds-worth of lag time between when changes to test.R in Vim are reflected in Rstudio.
Now there is a workaround, by using package ARTofR or bannerCommenter
Examples here:
In RStudio an easy way to do this is to write your comment and once you have used CTRL + Shift + C to comment your line of code, then use CTRL + SHIFT + / to reflow you comment onto multiple lines for ease of reading.
In RStudio you can use a pound sign and quote like this:
#' This is a comment
Now, every time you hit return you don't need to add the #', RStudio will automatically put that in for you.
Incidentally, for adding parameters and items that are returned, for standardization if you type an # symbol inside those comment strings, RStudio will automatically show you a list of codes associated with those comment parameters:
#' #param tracker_df Dataframe of limit names and limits
#' #param invoice_data Dataframe of invoice data
#' #return return_list List of scores for each limit and rejected invoice rows

Resources