How to programmatically generate R codes and directory structures with template
Asked Answered
W

1

13

I have the following Shiny-app, organize the following way

-- base_app
   |-- server.R
   |-- ui.R
   `-- www

For example, server.R contains this lines:

infile <- "foo.txt"
# do something with infile

I'm looking for a way to automatically generate the app directory and the file content. For example, if we define 2 parameters:

  1. App name mycool_app

  2. Input file: bar.txt

afterwards it will generate this based on the template defined in base_app.

-- mycool_app
   |-- server.R
   |-- ui.R
   `-- www

And the new server.R will contain infile <- "bar.txt".

I looked at whisker. But it doesn't provide the template encoded inside file, only through string. I'm thinking of the capability ala Python's Jinja2.

What are the best way to do it in R?


Update:

Another example for ui.R:

# Example of ui.R
# Choices differs from analysis to analysis
# Hand coded 
# ---------------------------
choices_list <- list(
                "A. Rumef.XXX vs Salt"            = "Group_A.Rumef.XXX_vs_Salt.iv",
                "B. Bra.XXX vs Salt"              = "Group_B.Bra.XXX_vs_Salt.iv",
                "C. Salt.Rumef vs Bra"            = "Group_C.Salt.Rumef_vs_Bra.iv",
                "D. XXX.Rumef vs Bra"             = "Group_D.XXX.Rumef_vs_Bra.iv"
                                                 )
selected_choices <- "Group_A.Rumef.XXX_vs_Salt.iv"
analysis_name <- "Cool Analysis"
fc_slider_threshold <- 0.8

# Do more things with those variables.

Content of choices_list, selected_choices, analysis_name, fc_slider_threshold will be supplied to be included in the newly generated mycool_app.

Wiring answered 21/7, 2017 at 6:25 Comment(5)
I'm not sure I understand. What is the difference between your question and simply copying the entire app folder from one location to another?Hurlbut
@Hurlbut I have many parameter-set and with that I want to create multiple apps. I want to automate that Shiny-apps generation.Wiring
Sorry, I am still not 100% clear. I see a server.R which contains infile <- "foo.txt", and that server.R file is also created in a different folder. What kind of parameters do you have and what kind of behavior do you expect them to perform? Right now it looks like file.copy() would work.Hurlbut
@Wiring are you looking for R or bash solution?Keeton
@PoGibas R, but welcome bash if it's reasonable.Wiring
P
10

not sure if I correctly understand what you need, but this piece of code seems to be doing what you want

genAppStr <- function(appname, infile) {
  dir.create(appname)
  dir.create(paste0(appname, "/www"))
  file.create(paste0(appname, "/", c("server.R", "ui.R")))
  writeLines(paste0("infile <- '", infile, "'"), paste0(appname, "/server.R"))
}

genAppStr("mycool_app", "bar.txt")

Or do you want to insert the contents of bar.txt into server.R?

With regard to the updated question:

genAppStr1 <- function(appname, infile, pars) {
  dir.create(appname)
  dir.create(paste0(appname, "/www"))
  file.create(paste0(appname, "/", c("server.R", "ui.R")))
  infilec <- readLines(infile)
  glued <- sapply(infilec, function(x) with(pars, glue(x)), USE.NAMES = FALSE)
  writeLines(as.character(glued), paste0(appname, "/server.R"))
}

Usage:

library(glue)

ch <- c("A. Rumef.XXX vs Salt"            = "Group_A.Rumef.XXX_vs_Salt.iv",
  "B. Bra.XXX vs Salt"              = "Group_B.Bra.XXX_vs_Salt.iv",
  "C. Salt.Rumef vs Bra"            = "Group_C.Salt.Rumef_vs_Bra.iv",
  "D. XXX.Rumef vs Bra"             = "Group_D.XXX.Rumef_vs_Bra.iv")

options(useFancyQuotes = FALSE)

vsQuote <- Vectorize(sQuote, USE.NAMES = FALSE)

makeChoiceList <- function(ch) {
  nms <- vsQuote(names(ch))
  chs <- vsQuote(ch)
  chnm <- paste(nms, chs, sep = " = ")
  paste0('list(', paste(chnm, collapse = ","), ')')
}

genAppStr1(
  "mycool_app", "infile.txt", 
  pars = list(
    par1 = makeChoiceList(ch),
    par2 = sQuote("Group_A.Rumef.XXX_vs_Salt.iv"),
    par3 = sQuote("Cool Analysis"),
    par4 = 0.8
  )
)

and the contents of infile.txt are

choices_list <- {par1}
selected_choices <- {par2}
analysis_name <- {par3}
fc_slider_threshold <- {par4}
Phlebotomy answered 21/7, 2017 at 7:0 Comment(2)
Thanks. What if I have more complex server code (multiple lines etc.) It would be more convenient to have a template no?Wiring
Maybe you can use glue for that. Can you give a simple example of what kind of server.R you would be generating?Phlebotomy

© 2022 - 2024 — McMap. All rights reserved.