Adam Jacobs
Adam Jacobs

Reputation: 423

Running an R package that expects interactive input non-interactively

I am a bit of a newbie when it comes to R programming, so please forgive me if this sounds obvious or misguided.

I am using an R package called bcrm (which does clever things for dose escalation for clinical trials in cancer), and when I run it interactively, it asks me for input via the terminal.

I would like to be able to run it non-interactively. Is there any way I can write a script that includes not only the command to invoke the bcrm package, but also the answer to the questions it asks subsequently?

Edit 21 Dec 2018: here's the code that asks me for interactive input. I'd love to put some code after the last bit of it (or maybe in a DOS batch script) that supplies the input, which consists of entering a series of numbers.

library(bcrm)

dose.levels <- c(1, 2, 3, 4)
prior.tox <- c(0.05, 0.1, 0.2, 0.3)
cohort.size <- 3
target.tox <- 0.33
max.size <- 6
prior.mean <- c(-0.5, 0.01)
prior.vcm <- matrix(c(0.5, 0.3, 0.3, 2), ncol=2)
prior.dist <- list(4, prior.mean, prior.vcm) 

tox.seq <- c(0, 0, 0)
dose.seq <- c(1, 1, 1)

mydata <- data.frame(patient = 1:3, dose=dose.seq, tox=tox.seq)




crm<-bcrm(dose = dose.levels,               # Dose levels
          p.tox0 = prior.tox,               # Prior probabilities of DLT
          target.tox = target.tox,          # Target tox level
          cohort = cohort.size,             # Cohort size
          stop = list(nmax = max.size),     # Stopping criteria
          ff = "logit2",                    # Model
          prior.alpha = prior.dist,         # Prior distribution on model parameter
          sdose.calculate = "median",       # How to calculate dose labels
          pointest = "plugin",              # How we will estimate DLT risks
          data = mydata,                    # Data so far
          simulate = FALSE,                 # Simulate lots of trials?
          method="rjags",                   # Calculation method
          truep = prior.tox,                # True probabilities, assume same as prior
          plot = TRUE)                      # Plot trial data as we go

Upvotes: 2

Views: 708

Answers (2)

Robin Beaumont
Robin Beaumont

Reputation: 11

Looking at the datastructure of the returned values it appears that you can extract the same output values as setting simulate=false, if you set simulate = True and nsims= 1

for example Setting simulate = false gives:

crm$ndose[[1]][[1]] # returns [1] 2

Setting simulate = true and nsims = 1 gives:

crm[[1]]$ndose[[1]][[1]]

returns 2 as before, all other values are the same as well.

Upvotes: 1

R Yoda
R Yoda

Reputation: 8760

Perhaps somebody proves my wrong (I hope so), but:

After trying to find some workarounds I think it is not possible to automatically inject the answers without changing the package source code (or finding a big hack).

Background

  1. The package bcrm uses standard R's readline function to accept interactive input (see source code, e. g. the function crm.interactive: https://github.com/cran/bcrm/blob/master/R/bcrm_0.4.7.R)

  2. readline does only work in interactive mode (see help):

    In non-interactive use the result is as if the response was RETURN and the value is "".

  3. If I try to execute your code in a (Linux) command line with enabled "interactive" mode (R --interactive < your_code.R) I have to use the input redirection to provide the R code and can therefor not redirect the input itself (and I guess it would be ignored since readline does not read stdin but the console).

  4. Rscript --interactive -e 'source("your_code.R") does not work neither (does not accept an "--interactive" argument).

So the possible solutions require changing the source code of the package to provide an alternative to using readline to support "interactive" answers e. g. from a file or an optional argument (please contact the author to ask to change this).

Since the source code is contained in one single file (see https://github.com/cran/bcrm/blob/master/R/bcrm_0.4.7.R) I guess you could just source it after applying some changes, e. g.

  1. replacing every call to readline() with my.readline()
  2. implement the function my.readline() by returning a single string "row" for each new call (you can take the value from a character vector and remember the index of the last called value).

Example:

cur.answer = 0
answers    = c("0", "1", "0")

my.readline <- function() {

  cur.answer <<- cur.answer + 1  # use "global" variable!
  
  if (cur.answer <= length(answers))
    return (answers[cur.answer])
  
  return ("")  # default
}

my.readline()
# [1] "0"
my.readline()
# [1] "1"
my.readline()
# [1] "0"
my.readline()
# [1] ""

Upvotes: 0

Related Questions