Combine two outputs in a single box in RStudio - r

I am extremely new to R.
This simple code prints two outputs:
ec_lineal = function(a,b){
print(sprintf('%i x + %i = 0',a,b))
paste(sprintf('x ='), -b / a)
}
ec_lineal(5,3)
[1] "5 x + 3 = 0"
[1] "x = -0.6"
When I knit the code to HTML, I get separate boxes for each of the outputs:
Is there any way to combine both outputs in a single white box?
Maybe editing the code chunk header ```{r} ?
I am using R 3.6.3 and the latest version of RStudio in Windows 10.
Thank you.

You may use cat.
ec_lineal = function(a,b) {
cat(sprintf('%i x + %i = 0',a,b),
paste(sprintf('x ='), -b / a),
sep="\n")
}
ec_lineal(5,3)
# 5 x + 3 = 0
# x = -0.6

Related

How to quietly change the System Locale in R [duplicate]

I'm looking to suppress the output of one command (in this case, the apply function).
Is it possible to do this without using sink()? I've found the described solution below, but would like to do this in one line if possible.
How to suppress output
It isn't clear why you want to do this without sink, but you can wrap any commands in the invisible() function and it will suppress the output. For instance:
1:10 # prints output
invisible(1:10) # hides it
Otherwise, you can always combine things into one line with a semicolon and parentheses:
{ sink("/dev/null"); ....; sink(); }
Use the capture.output() function. It works very much like a one-off sink() and unlike invisible(), it can suppress more than just print messages. Set the file argument to /dev/null on UNIX or NUL on windows. For example, considering Dirk's note:
> invisible(cat("Hi\n"))
Hi
> capture.output( cat("Hi\n"), file='NUL')
>
The following function should do what you want exactly:
hush=function(code){
sink("NUL") # use /dev/null in UNIX
tmp = code
sink()
return(tmp)
}
For example with the function here:
foo=function(){
print("BAR!")
return(42)
}
running
x = hush(foo())
Will assign 42 to x but will not print "BAR!" to STDOUT
Note than in a UNIX OS you will need to replace "NUL" with "/dev/null"
R only automatically prints the output of unassigned expressions, so just assign the result of the apply to a variable, and it won't get printed.
you can use 'capture.output' like below. This allows you to use the data later:
log <- capture.output({
test <- CensReg.SMN(cc=cc,x=x,y=y, nu=NULL, type="Normal")
})
test$betas
In case anyone's arriving here looking for a solution applicable to RMarkdown, this will suppress all output:
```{r error=FALSE, warning=FALSE, message=FALSE}
invisible({capture.output({
# Your code goes here
2 * 2
# etc
# etc
})})
```
The code will run, but the output will not be printed to the HTML document
invisible(cat("Dataset: ", dataset, fill = TRUE))
invisible(cat(" Width: " ,width, fill = TRUE))
invisible(cat(" Bin1: " ,bin1interval, fill = TRUE))
invisible(cat(" Bin2: " ,bin2interval, fill = TRUE))
invisible(cat(" Bin3: " ,bin3interval, fill = TRUE))
produces output without NULL at the end of the line or on the next line
Dataset: 17 19 26 29 31 32 34 45 47 51 52 59 60 62 63
Width: 15.33333
Bin1: 17 32.33333
Bin2: 32.33333 47.66667
Bin3: 47.66667 63
Making Hadley's comment to an answer: Use of apply family without printing is possible with use of the plyr package
x <- 1:2
lapply(x, function(x) x + 1)
#> [[1]]
#> [1] 2
#>
#> [[2]]
#> [1] 3
plyr::l_ply(x, function(x) x + 1)
Here is a version that is robust to errors in the code to be shushed:
quietly <- function(x) {
sink("/dev/null") # on Windows (?) instead use `sink("NUL")`
tryCatch(suppressMessages(x), finally = sink())
}
This is based directly on the accepted answer, for which thanks.
But it avoids leaving output silenced if an error occurs in the quieted code.

Print text with subscripts (programatically) to R console

I'm using R to balance some complex chemical equations and would like to print these equations including subscripts to the console as the code runs. I've seen some answers posted, most of which are related to plots or rely on pasting the subscript from another program into R scripts:
Subscripts in R when adding other text
How to literally print superscripts in R not used in labels or legends?
Using Subscripts and Superscripts in R console
Unicode subscript in R had some pointers that were helpful. I can get the appropriate code from this link but it doesn't allow me to programatically create the code for the character I want.
CODE
Here's a simple example equation for combustion of methane that works:
> sub2 <- '\u2082' # hard-coding unicode for '2' as a subscript
> sub4 <- '\u2084' # hard-coding unicode for '4' as a subscript
> cat(sprintf('CH%s + 2 O%s --> CO%s + 2 H%sO', sub4, sub2, sub2, sub2))
CH₄ + 2 O₂ --> CO₂ + 2 H₂O
Lengthy workaround (proof-of-concept):
desired_subscript <- 3.375
subs <- c('\u2080', '\u2081', '\u2082', '\u2083', '\u2084',
'\u2085', '\u2086', '\u2087', '\u2088', '\u2089')
charvec <- as.character(x = desired_subscript)
lapply(0:9, function(z){
charvec <<- gsub(pattern = z, replacement = subs[z+1], x = charvec)
return(NULL)
})
> cat(charvec)
₃.₃₇₅
Here's what doesn't work:
replacing the last digit of the unicode string to what I want:
> cat(sub(pattern = '2', replacement = '4', x = sub2))
₂
Trying to create a unicode string:
> paste('\208','4',sep = '')
[1] "\02084"
I have multiple equations to balance and the subscripts are not always whole numbers. Is there a way to programatically get unicode for the subscript that I want to include in my output to console?
Try this
create a function to return unicodes. Caution: No error checking
ss <- function(x) {intToUtf8(0x2080 + x)}
cat(sprintf('CH%s + 2 O%s --> CO%s + 2 H%sO', ss(4), ss(2), ss(2), ss(2)))

How do I get a shorter Runtime?

num<-18.7
guess<- -1
print("Can you guess the daily dose per 1000 inhabititants in the UK?")
while(guess !=num) {
guess<-readline(prompt = "Enter integer:")
if (guess== num)
cat(num, "is correct")
if (guess<num)
cat("it is bigger")
if (guess>num)
cat("It is smaller")
}
It works when I play it through r script but when I knit it into markdown it doesn't get an error or anything but its been running for about 30 minutes and still hasn't finished. Is there a way to change this?
As mentioned in the comments, the R code in a R Markdown document is executed when it is knitted, not when it is viewed. When talking about interactivity for R, one usually thinks about Shiny. For some cases it is also possible to combine Shiny directly with R Markdown, c.f. https://bookdown.org/yihui/rmarkdown/shiny-documents.html. A straight forward conversion of your script gives:
---
runtime: shiny
output: html_document
---
# Can you guess the daily dose per 1000 inhabititants in the UK?
```{r setup, include=FALSE}
num <- 18.7
```
```{r guessing-game, echo=FALSE}
numericInput("guess", label = "Enter number:", value = 0)
renderText({
if (input$guess == num)
paste(num, "is correct")
else if (input$guess<num)
"it is bigger"
else if (input$guess>num)
"It is smaller"
})
```
Such a document can either be run locally or deployed. BTW, == is not the best choice for comparing floating point numbers. It is better to use isTRUE(all.equal()):
> 0.3 == 0.1 + 0.1 + 0.1
[1] FALSE
> isTRUE(all.equal(0.3, 0.1 + 0.1 + 0.1))
[1] TRUE

Save plot without showing it at all

Is it possible to save a plot without displaying it at all ?
I made a little ggplot hack to be able to copy graphs to powerpoint easily, it copies the plot to the clipboard, but one can see the device window open and close fast, it's a bit awkward, can I avoid this ?
I'm using windows and rstudio.
reproducible code:
library(ggplot)
`-.gg` <- function(e1,e2){
assertthat::assert_that(is.numeric(e2),
length(e2)<= 2)
if(identical(e2,0)) return(invisible(NULL))
W <- 8
H <- 4.5
dev.new(width=W * head(e2,1), height=H * tail(e2,1),noRStudioGD =TRUE)
print(e1)
savePlot("clipboard", type="wmf")
dev.off()
e1
}
ggplot(data.frame(x=1:10,y=1:10),aes(x,y)) + geom_point() - 1 - 0
Edit:
My code, and chosen solution, have issues dealing with semi-transparency.It's ok most of the time, but exceptions will be annoying.
Maybe a path to a general solution would be to save it with tempfile then read it into the clipboard, either through an appropriate R function, or with command line using system (maybe something that would open the file invisibly and copy).
This works on Windows: use the win.metafile() device. If you give no filename, it saves to the clipboard. So your function should be
library(ggplot2)
`-.gg` <- function(e1,e2){
assertthat::assert_that(is.numeric(e2),
length(e2)<= 2)
if(identical(e2,0)) return(invisible(NULL))
W <- 8
H <- 4.5
win.metafile(width=W * head(e2,1), height=H * tail(e2,1))
print(e1)
dev.off()
e1
}
ggplot(data.frame(x=1:10,y=1:10),aes(x,y)) + geom_point() - 1 - 0
On windows and R 3.4.2, using Sys.sleep was able to view the plot instead of blink and miss
`-.gg` <- function(e1,e2){
assertthat::assert_that(is.numeric(e2),
length(e2)<= 2)
if(identical(e2,0)) return(invisible(NULL))
W <- 8
H <- 4.5
dev.new(width=W * head(e2,1), height=H * tail(e2,1),noRStudioGD =TRUE)
print(e1)
savePlot("clipboard", type="wmf")
Sys.sleep(3) ##
dev.off()
e1
}
ggplot(data.frame(x=1:10,y=1:10),aes(x,y)) + geom_point() - 1 - 0

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 (e.g. '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.

Resources