简体   繁体   中英

How to convert code to more readable form in R

I copy code from the terminal to post here. It is in following form:

> ddf2 = ddf[ddf$stone_ny>'stone',] # this is first command
> ddf2[!duplicated(ddf2$deltnr),]   # second command
   deltnr us stone_ny stone_mobility      
4    1536 63    stone         mobile 
10   1336 62    stone         mobile 

First 2 lines are commands while next 3 lines are output. However, this cannot be copied from here back to R terminal since the commands start with '> '. How can I convert this to:

ddf2 = ddf[ddf$stone_ny>'stone',] # this is first command
ddf2[!duplicated(ddf2$deltnr),]   # second command
#   deltnr us stone_ny stone_mobility      
#4    1536 63    stone         mobile 
#10   1336 62    stone         mobile 

So that it become suitable for copying from here.

I tried:

text
[1] "> ddf2 = ddf[ddf$stone_ny>'stone',] # this is first command\n> ddf2[!duplicated(ddf2$deltnr),]   # second command\n   deltnr us stone_ny stone_mobility      \n4    1536 63    stone         mobile \n10   1336 62    stone         mobile "


text2 = gsub('\n','#',text)
text2 = gsub('#>','\n',text2)
text2 = gsub('#','\n#',text2)
text2
[1] "> ddf2 = ddf[ddf$stone_ny>'stone',] \n# this is first command\n 
ddf2[!duplicated(ddf2$deltnr),]   \n# second command\n#   deltnr us stone_ny stone_mobility      \n#4    1536 63    stone         mobile \n#10   1336 62    stone         mobile "

But it cannot get pasted to the terminal.

I've been waiting for an opportunity to share this function I keep in my .Rprofile file. While it may not answer exactly your question, I feel it is accomplishing something very close to what you are after. So you might get some ideas by looking at its code. And others might find it useful just as it is. The function:

SO <- function(script.file = '~/.active-rstudio-document') {

   # run the code and store the output in a character vector
   tmp <- tempfile()
   capture.output(
      source(script.file, echo = TRUE, 
                          prompt.echo = "> ",
                          continue.echo = "+ "), file = tmp)
   out <- readLines(tmp)

   # identify lines that are comments, code, results
   idx.comments <- grep("^> [#]{2}", out)
   idx.code     <- grep("^[>+] ", out)
   idx.blank    <- grep("^[[:space:]]*$", out)
   idx.results  <- setdiff(seq_along(out),
                           c(idx.comments, idx.code, idx.blank))
   # reformat
   out[idx.comments] <- sub("^> [#]{2} ", "", out[idx.comments])
   out[idx.code]     <- sub("^[>+] ", "    ", out[idx.code])
   out[idx.results]  <- sub("^", "    # ", out[idx.results])

   # output
   cat(out, sep = "\n", file = stdout())
}

This SO function is what allows me to quickly format my answers to questions on this very website, StackOverflow. My workflow is as follows:

1) In RStudio, write my answer in an untitled script (that's the top-left quadrant). For example:

## This is super easy, you can do

set.seed(123)
# initialize x
x <- 0
while(x < 0.5) {
   print(x)
   # update x
   x <- runif(1)
}

## And voila.

2) Near the top, click the "Source" button. It will execute the code in the console which is not really what we are after: rather, it will have the side effect of saving the code to the default file '~/.active-rstudio-document'.

3) Run SO() from the console (bottom-left quadrant) which will source the code (again...) from the saved file, capture the output and print it in a SO-friendly format:

This is super easy, you can do

    set.seed(123)
    # initialize x
    x <- 0
    while(x < 0.5) {
       print(x)
       # update x
       x <- runif(1)
    }
    # [1] 0
    # [1] 0.2875775

And voila.

4) Copy-paste into stackoverflow and done.

Note: For code that takes a while to run, you can avoid running it twice by saving your script to a file (eg 'xyz.R') instead of clicking the "Source" button. Then run SO("xyz.R") .

You could try cat with an ifelse condition.

cat(ifelse(substr(s <- strsplit(text, "\n")[[1]], 1, 1) %in% c("_", 0:9, " "), 
           paste0("# ", s), 
           gsub("[>] ", "", s)), 
    sep = "\n")

which results in

ddf2 = ddf[ddf$stone_ny>'stone',] # this is first command
ddf2[!duplicated(ddf2$deltnr),]   # second command
#    deltnr us stone_ny stone_mobility      
# 4    1536 63    stone         mobile 
# 10   1336 62    stone         mobile 

The "_" and 0:9 are in there because one of the rules in R is that a function cannot begin with a _ or a digit. You can adjust it to fit your needs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM