Multiline Comment Workarounds? - r

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

Related

Is there a way to let the console in RStudio produce time stamps? [duplicate]

I wonder if there is a way to display the current time in the R command line, like in MS DOS, we can use
Prompt $T $P$G
to include the time clock in every prompt line.
Something like
options(prompt=paste(format(Sys.time(), "%H:%M:%S"),"> "))
will do it, but then it is fixed at the time it was set. I'm not sure how to make it update automatically.
Chase points the right way as options("prompt"=...) can be used for this. But his solutions adds a constant time expression which is not what we want.
The documentation for the function taskCallbackManager has the rest:
R> h <- taskCallbackManager()
R> h$add(function(expr, value, ok, visible) {
+ options("prompt"=format(Sys.time(), "%H:%M:%S> "));
+ return(TRUE) },
+ name = "simpleHandler")
[1] "simpleHandler"
07:25:42> a <- 2
07:25:48>
We register a callback that gets evaluated after each command completes. That does the trick. More fancy documentation is in this document from the R developer site.
None of the other methods, which are based on callbacks, will update the prompt unless a top-level command is executed. So, pressing return in the console will not create a change. Such is the nature of R's standard callback handling.
If you install the tcltk2 package, you can set up a task scheduler that changes the option() as follows:
library(tcltk2)
tclTaskSchedule(1000, {options(prompt=paste(Sys.time(),"> "))}, id = "ticktock", redo = TRUE)
Voila, something like the MS DOS prompt.
NB: Inspiration came from this answer.
Note 1: The wait time (1000 in this case) refers to the # of milliseconds, not seconds. You might adjust it downward when sub-second resolution is somehow useful.
Here is an alternative callback solution:
updatePrompt <- function(...) {options(prompt=paste(Sys.time(),"> ")); return(TRUE)}
addTaskCallback(updatePrompt)
This works the same as Dirk's method, but the syntax is a bit simpler to me.
You can change the default character that is displayed through the options() command. You may want to try something like this:
options(prompt = paste(Sys.time(), ">"))
Check out the help page for ?options for a full list of things you can set. It is a very useful thing to know about!
Assuming this is something you want to do for every R session, consider moving that to your .Rprofile. Several other good nuggets of programming happiness can be found hither on that topic.
I don't know of a native R function for doing this, but I know R has interfaces with other languages that do have system time commands. Maybe this is an option?
Thierry mentioned system.time() and there is also proc.time() depending on what you need it for, although neither of these give you the current time.

print entire string to console without truncating and without adjusting a global setting

I have read these SO posts on getting rstudio to print out without truncating:
list output truncated - How to expand listed variables with str() in R
avoid string printed to console getting truncated (in RStudio)
The answers there involve making a adjustment to studio settings which would then cover all future outputs to the console.
Is there a ad hoc way to get r to print an entire string to the console?
I tried:
library(tidyverse)
library(foreach)
mystring <- foreach(i = 1:52) %do% {
paste0("'_gaWeek",i,"'!A16:B;")
} %>% unlist %>% toString()
print(mystring, len = length(mystring))
> print(mystring, len = length(mystring))
[1] "'_gaWeek1'!A16:B;, '_gaWeek2'!A16:B;, '_gaWeek3'!A16:B;, '_gaWeek4'!A16:B;, '_gaWeek5'!A16:B;, '_gaWeek6'!A16:B;, '_gaWeek7'!A16:B;, '_gaWeek8'!A16:B;, '_gaWeek9'!A16:B;, '_gaWeek10'!A16:B;, '_gaWeek11'!A16:B;, '_gaWeek12'!A16:B;, '_gaWeek13'!A16:B;, '_gaWeek14'!A16:B;, '_gaWeek15'!A16:B;, '_gaWeek16'!A16:B;, '_gaWeek17'!A16:B;, '_gaWeek18'!A16:B;, '_gaWeek19'!A16:B;, '_gaWeek20'!A16:B;, '_gaWeek21'!A16:B;, '_gaWeek22'!A16:B;, '_gaWeek23'!A16:B;, '_gaWeek24'!A16:B;, '_gaWeek25'!A16:B;, '_gaWeek26'!A16:B;, '_gaWeek27'!A16:B;, '_gaWeek28'!A16:B;, '_gaWeek29'!A16:B;, '_gaWeek30'!A16:B;, '_gaWeek31'!A16:B;, '_gaWeek32'!A16:B;, '_gaWeek33'!A16:B;, '_gaWeek34'!A16:B;, '_gaWeek35'!A16:B;, '_gaWeek36'!A16:B;, '_gaWeek37'!A16:B;, '_gaWeek38'!A16:B;, '_gaWeek39'!A16:B;, '_gaWeek40'!A16:B;, '_gaWeek41'!A16:B;, '_gaWeek42'!A16:B;, '_gaWeek43'!A16:B;, '_gaWeek44'!A16:B;, '_gaWeek45'!A16:B;, '_gaWeek46'!A16:B;, '_gaWeek47'!A16:B;, '_gaWeek48'!A16:B;, '_gaWeek49'!A16:B;, '_gaWeek50'!A16:B;, '_ga... <truncated>
It's truncated. Is there an ad hoc way around this without changing rstudio settings? Such as by a function argument? I tried print() here.
Also, how do I get rid of the comma separator in between each instance above?
The short answer is "no" since, the option limiting the print is in the IDE itself, which you can't control from your program itself (I'm assuming you're not some crazy hacker here), and not a language feature. It's like trying to stop "WINDOWS" from doing things (although not).
Seems to me the easiest way (ad hoc) is to turn it on, do whatever, then turn it off. If you insist on not doing that, you need to write your own function:
myprint<- function(somestring,idelimit=100) {
for(i in seq(1,nchar(somestring),idelimit+1)) {
print(substr(somestring,i,i+idelimit));
}
}
I'm not a fluent R coder so let me know if you catch a syntax error. The idea is simple - idelimit should be wherever studio truncates (I chose 100 arbitrarily), and basically you're doing the splitting yourself so string is printed line after line without truncation. Each time you take a portion at most idelimit long from somestring and print it.

Running R script_Readline and Scan does not pause for user input

I have looked at other posts that appeared similar to this question but they have not helped me. This may be just my ignorance of R. Thus I decided to sign up and make my first post on stack-overflow.
I am running an R-script and would like the user to decide either to use one of the two following loops. The code to decide user input looks similar to the one below:
#Define the function
method.choice<-function() {
Method.to.use<-readline("Please enter 'New' for new method and'Old' for old method: ")
while(Method.to.use!="New" && Method.to.use!="Old"){ #Make sure selection is one of two inputs
cat("You have not entered a valid input, try again", "\n")
Method.to.use<-readline("Please enter 'New' for new method and 'Old' for old method: ")
cat("You have selected", Method.to.use, "\n")
}
return(Method.to.use)
}
#Run the function
method.choice()
Then below this I have the two possible choices:
if(Method.to.use=="New") {
for(i in 1:nrow(linelist)){...}
}
if(Method.to.use=="Old"){
for(i in 1:nrow(linelist)){...}
}
My issue is, and what I have read from other posts, is that whether I use "readline", "scan" or "ask", R does not wait for my input. Instead R will use the following lines as the input.
The only way I found that R would pause for input is if the code is all on the same line or if it is run line by line (instead of selecting all the code at once). See example from gtools using "ask":
silly <- function()
{
age <- ask("How old are you? ")
age <- as.numeric(age)
cat("In 10 years you will be", age+10, "years old!\n")
}
This runs with a pause:
silly(); paste("this is quite silly")
This does not wait for input:
silly()
paste("this is quite silly")
Any guidance would be appreciated to ensure I can still run my entire script and have it pause at readline without continuing. I am using R-studio and I have checked that interactive==TRUE.
The only other work-around I found is wrapping my entire script into one main function, which is not ideal for me. This may require me to use <<- to write to my environment.
Thank you in advance.

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.

Is it possible to have a multi-line comments in R? [duplicate]

This question already has answers here:
Multiline Comment Workarounds?
(11 answers)
Closed 9 years ago.
I found this old thread (from over a year ago), which explains how come R doesn't support a multi-line comments (like /* comment */ of PHP, for example).
I am wondering if this has been resolved in the past year, or if there are other alternatives? (For example, in notepad++ with npptor, you can mark a bunch of lines and press ctrl+q to mark them all as comments, are there similar solutions for other IDE's ?)
R Studio (and Eclipse + StatET): Highlight the text and use CTRL+SHIFT+C to comment multiple lines in Windows.
For macOS, use command+SHIFT+C.
You can, if you want, use standalone strings for multi-line comments — I've always thought that prettier than if (FALSE) { } blocks. The string will get evaluated and then discarded, so as long as it's not the last line in a function nothing will happen.
"This function takes a value x, and does things and returns things that
take several lines to explain"
doEverythingOften <- function(x) {
# Non! Comment it out! We'll just do it once for now.
"if (x %in% 1:9) {
doTenEverythings()
}"
doEverythingOnce()
...
return(list(
everythingDone = TRUE,
howOftenDone = 1
))
}
The main limitation is that when you're commenting stuff out, you've got to watch your quotation marks: if you've got one kind inside, you'll have to use the other kind for the comment; and if you've got something like "strings with 'postrophes" inside that block, then there's no way this method is a good idea. But then there's still the if (FALSE) block.
The other limitation, one that both methods have, is that you can only use such blocks in places where an expression would be syntactically valid - no commenting out parts of lists, say.
Regarding what do in which IDE: I'm a Vim user, and I find
NERD Commenter an utterly excellent tool for quickly commenting or uncommenting multiple lines. Very user-friendly, very well-documented.
Lastly, at the R prompt (at least under Linux), there's the lovely Alt-Shift-# to comment the current line. Very nice to put a line 'on hold', if you're working on a one-liner and then realise you need a prep step first.
CTRL+SHIFT+C in Eclipse + StatET and Rstudio.
if(FALSE) {
...
}
precludes multiple lines from being executed. However, these lines still have to be syntactically correct, i.e., can't be comments in the proper sense. Still helpful for some cases though.
No multi-line comments in R as of version 2.12 and unlikely to change. In most environments, you can comment blocks by highlighting and toggle-comment. In emacs, this is 'M-x ;'.
Put the following into your ~/.Rprofile file:
exclude <- function(blah) {
"excluded block"
}
Now, you can exclude blocks like follows:
stuffiwant
exclude({
stuffidontwant
morestuffidontwant
})
Unfortunately, there is still no multi-line commenting in R.
If your text editor supports column-mode, then use it to add a bunch of #s at once. If you use UltraEdit, Alt+c will put you in column mode.

Resources