R:动态构造和执行命令

时间:2016-01-19 16:49:31

标签: r shiny

根据用户输入,我需要使用不同的调色板。用户输入可以采用四个(字符)值:grayheatterrainrainbow。而不是编写一系列if语句,直接做类似的事情会很优雅:

palette = cat(user_input,".colors(n=10)",sep="")或与paste0相同......

cat(user_input,".colors(n=10)",sep="")确实给了我gray.colors(n=10),但它只是粘贴文本,而不是评估命令,所以没有任何反应,如果我将输出保存为palette对象,它只是文本正在被救。

注意:如果标题的措辞不合适,请抱歉。我不是来自CS,我不知道应该如何调用此任务。并给出一些背景信息,这是一个闪亮的应用程序

2 个答案:

答案 0 :(得分:2)

您想评估已解析的文字:

> eval(parse(text="gray.colors(n=10)"))
 [1] "#4D4D4D" "#6C6C6C" "#838383" "#969696" "#A7A7A7" "#B5B5B5" "#C3C3C3"
 [8] "#CFCFCF" "#DBDBDB" "#E6E6E6"

可以评估任何文本并以这种方式运行。请注意,如果此字符串可由用户设置并发送到服务器,则可能有一种方法可以在服务器上运行任意代码。在从这样的客户端运行代码之前,请确保验证服务器上允许的调色板功能(搜索" XKCD Bobby Tables"了解更多信息)。

另一种选择是使用do.call,它使用函数名的字符串:

> do.call("gray.colors",list(n=10))
 [1] "#4D4D4D" "#6C6C6C" "#838383" "#969696" "#A7A7A7" "#B5B5B5" "#C3C3C3"
 [8] "#CFCFCF" "#DBDBDB" "#E6E6E6"

并且可能不太容易受到代码注入漏洞的影响。

答案 1 :(得分:1)

我认为你的应用太复杂了;你这里不需要eval。相反,为用户提供选择的调色板,然后使用它从列表中查找函数。

这是一个基于闪亮的旧忠实例子的例子:

shinyServer(function(input, output) {

  # List of palette functions
  my_palettes <- list(Rainbow=rainbow,
                      Heat=heat.colors,
                      Terrain=terrain.colors,
                      Topo=topo.colors)

  # Provide a drop down for palette
  output$palette <- renderUI(selectInput("palette", "Palette:", names(my_palettes), names(my_palettes)[1]))

  output$distPlot <- renderPlot({

    # generate bins based on input$bins from ui.R
    x    <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)

    # look up palette function from list, call it with n=bins
    palette = my_palettes[[input$palette]](input$bins)

    # draw the histogram with the specified number of bins
    hist(x, breaks = bins, col = palette, border = 'white')
  })

})