根据用户输入,我需要使用不同的调色板。用户输入可以采用四个(字符)值:gray
,heat
,terrain
和rainbow
。而不是编写一系列if语句,直接做类似的事情会很优雅:
palette = cat(user_input,".colors(n=10)",sep="")
或与paste0
相同......
cat(user_input,".colors(n=10)",sep="")
确实给了我gray.colors(n=10)
,但它只是粘贴文本,而不是评估命令,所以没有任何反应,如果我将输出保存为palette
对象,它只是文本正在被救。
注意:如果标题的措辞不合适,请抱歉。我不是来自CS,我不知道应该如何调用此任务。并给出一些背景信息,这是一个闪亮的应用程序。
答案 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')
})
})