Пользовательский ввод в неинтерактивном сеансе Knitr - PullRequest
0 голосов
/ 10 мая 2018

Я работаю над слайдами, на которых хочу показать вывод, сгенерированный debugger(), и выйти.Вязание застревает на чанке, так как ожидает ввода пользователя, который, в моем случае, будет 0.Есть ли способ заставить RStudio вязать в интерактивном режиме?

1 Ответ

0 голосов
/ 11 мая 2018

Попробуйте использовать пакет R подпроцесс для запуска некоторого кода в отдельном сеансе R.Следующий пример был построен с использованием фрагментов кода, предоставленных в виньетке 'intro' из пакета подпроцесса, и примера, предоставленного в файле справки для debugger.

Покупка, запускающая код debugger у дочернего элемента.В этом процессе вы можете написать сценарий взаимодействия, необходимого для фрагментов кода R вашего основного документа.

Пример .Rmd-файла:

---
title: 'Debugger in a knited doc'
output: html_document
---


```{r label='internal-setup', include=FALSE}
knitr::opts_chunk$set(collapse = TRUE)
```


Try using the R package
[subprocess](https://cran.r-project.org/package=subprocess) to run some code
in a seperate R session.  The following example has been built using code
snippets provided in the 'intro' vignette from the subprocess package and the
example provided in the help file for `debugger`.

The first thing we will do is build a function for calling the R binary.


```{r label="setup_subprocess"}
library(subprocess)

R_binary <- function () {
  R_exe <- ifelse (tolower(.Platform$OS.type) == "windows", "R.exe", "R")
  return(file.path(R.home("bin"), R_exe))
}
```


Spawning a child R process is done as follows:


```{r label="spawning"}
child_r <- subprocess::spawn_process(R_binary(), c("--vanilla"))
Sys.sleep(2) # allow sufficient time for the child R process to start
subprocess::process_read(child_r)$stdout
```


We will write some code as a character string and send it to the child
process.


```{r }
unlink("testdump.rda")
code <-
'
options(error = quote(dump.frames("testdump", TRUE)))

f <- function() {
  g <- function() stop("test dump.frames")
  g()
}
f()   # will generate a dump on file "testdump.rda"
options(error = NULL)
'

invisible(subprocess::process_write(child_r, code))
subprocess::process_read(child_r)$stdout
```


Now, you can load the dump into the child process and start the debugger.

```{r }
code <-
'
load("testdump.rda")
debugger(testdump)
'
invisible(subprocess::process_write(child_r, code))
subprocess::process_read(child_r)$stdout
```


Say you want to start walking through the debugger for `f(1)`

```{r }
invisible(subprocess::process_write(child_r, "1\n"))
subprocess::process_read(child_r)$stdout
```


You can continue to walk through the debugging as needed via the child
process.

Don't forget to terminate the process

```{r }
subprocess::process_terminate(child_r)
```

Этот документ привел к созданию HTML-страницы, которая выглядела так:

Отладчик в связанном документе

Попробуйте использовать подпроцесс пакета R для запуска некоторого кода в отдельном сеансе R.Следующий пример был построен с использованием фрагментов кода, предоставленных в виньетке 'intro' из пакета подпроцесса, и примера, приведенного в файле справки для отладчика.

Первое, что мы сделаем, это построим функцию для вызоваДвоичный файл R.

library(subprocess)

R_binary <- function () {
  R_exe <- ifelse (tolower(.Platform$OS.type) == "windows", "R.exe", "R")
  return(file.path(R.home("bin"), R_exe))
}

Создание дочернего процесса R выполняется следующим образом:

child_r <- subprocess::spawn_process(R_binary(), c("--vanilla"))
Sys.sleep(2) # allow sufficient time for the child R process to start
subprocess::process_read(child_r)$stdout
##  [1] ""                                                             
##  [2] "R version 3.5.0 (2018-04-23) -- \"Joy in Playing\""           
##  [3] "Copyright (C) 2018 The R Foundation for Statistical Computing"
##  [4] "Platform: x86_64-apple-darwin17.5.0 (64-bit)"                 
##  [5] ""                                                             
##  [6] "R is free software and comes with ABSOLUTELY NO WARRANTY."    
##  [7] "You are welcome to redistribute it under certain conditions." 
##  [8] "Type 'license()' or 'licence()' for distribution details."    
##  [9] ""                                                             
## [10] "  Natural language support but running in an English locale"  
## [11] ""                                                             
## [12] "R is a collaborative project with many contributors."         
## [13] "Type 'contributors()' for more information and"               
## [14] "'citation()' on how to cite R or R packages in publications." 
## [15] ""                                                             
## [16] "Type 'demo()' for some demos, 'help()' for on-line help, or"  
## [17] "'help.start()' for an HTML browser interface to help."        
## [18] "Type 'q()' to quit R."                                        
## [19] ""                                                             
## [20] "> "

Мы напишем некоторый код в виде строки символов и отправим его дочернему процессу.

unlink("testdump.rda")
code <-
'
options(error = quote(dump.frames("testdump", TRUE)))

f <- function() {
  g <- function() stop("test dump.frames")
  g()
}
f()   # will generate a dump on file "testdump.rda"
options(error = NULL)
'

invisible(subprocess::process_write(child_r, code))
subprocess::process_read(child_r)$stdout
## [1] ""                                                         
## [2] "> options(error = quote(dump.frames(\"testdump\", TRUE)))"
## [3] "> "                                                       
## [4] "> f <- function() {"                                      
## [5] "+   g <- function() stop(\"test dump.frames\")"           
## [6] "+   g()"                                                  
## [7] "+ }"                                                      
## [8] "> f()   # will generate a dump on file \"testdump.rda\""

Теперь вы можете загрузить дамп в дочерний процесс и запустить отладчик.

code <-
'
load("testdump.rda")
debugger(testdump)
'
invisible(subprocess::process_write(child_r, code))
subprocess::process_read(child_r)$stdout
##  [1] "> options(error = NULL)"                               
##  [2] "> "                                                    
##  [3] "> load(\"testdump.rda\")"                              
##  [4] "> debugger(testdump)"                                  
##  [5] "Message:  Error in g() : test dump.frames"             
##  [6] "Calls: f -> g"                                         
##  [7] "Available environments had calls:"                     
##  [8] "1: f()"                                                
##  [9] "2: g()"                                                
## [10] "3: stop(\"test dump.frames\")"                         
## [11] ""                                                      
## [12] "Enter an environment number, or 0 to exit  Selection: "

Допустим, вы хотите начать обходить отладчик для f (1)

invisible(subprocess::process_write(child_r, "1\n"))
subprocess::process_read(child_r)$stdout
## [1] "1"                                     
## [2] "Browsing in the environment with call:"
## [3] "   f()"                                
## [4] "Called from: debugger.look(ind)"       
## [5] "Browse[1]> "

Вы можете продолжить отладку по мере необходимости через дочерний процесс.

Не забудьте прекратить процесс

subprocess::process_terminate(child_r)
## [1] TRUE

Вы можете получить копии фактическогофайлы с моей страницы github .

...