如何使用模板以编程方式生成R代码和目录结构

时间:2017-07-21 06:25:34

标签: r shiny templating

我有以下Shiny-app,按照以下方式组织

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

例如,server.R包含以下行:

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

我正在寻找一种自动生成应用目录和文件内容的方法。例如,如果我们定义2个参数:

  1. 应用名称mycool_app

  2. 输入文件:bar.txt

  3. 之后,它将根据base_app中定义的模板生成此内容。

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

    新的server.R将包含infile <- "bar.txt"

    我看着 whisker。但它不能通过字符串提供内部文件编码的模板。我正在考虑能力ala Python's Jinja2

    在R中执行此操作的最佳方式是什么?

    更新

    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.
    

    将提供choices_listselected_choicesanalysis_namefc_slider_threshold的内容,以包含在新生成的mycool_app中。

1 个答案:

答案 0 :(得分:9)

不确定我是否正确理解了您的需求,但这段代码似乎正在做您想做的事情

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")

或者您想将bar.txt的内容插入server.R?

关于更新的问题:

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"))
}

用法:

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
  )
)

并且infile.txt的内容是

choices_list <- {par1}
selected_choices <- {par2}
analysis_name <- {par3}
fc_slider_threshold <- {par4}