前面3节的内容都没有涉及数据处理,恐怕有人等不及了。R语言的强项是统计和图形处理,拿它去做网页设计是不是舍本逐末?确实,我觉得也是这样。如果不是为其他客户专门开发的应用,我们不应把时间浪费在外观设计上。多关心数据,多考虑我们需要获得的结果。
本文先介绍shiny的输出方法,后面再介绍数据输入和响应。这里说的“输出”是动态的输出或必需使用R函数处理才能够获得的输出。完全静态的文字或图像的输出应把它归到前面的UI设计部分。
1 Shiny输出语法
先看下面例子:
shinyApp( ui = fixedPage( textOutput('tx', container=h1), plotOutput('pl', width='100%', height='400px') ), server = function(input, output, session) { output$tx <- renderText({ "这是服务器输出的文字" }) output$pl <- renderPlot({ a <- rnorm(20) par(mar=c(3, 3, 0.5, 0.5), mgp=c(2, 0.5, 0)) plot(a) }) } )
保存和运行该程序后产生的结果如下:
可以看出,Shiny的动态输出需要ui和server两部分的共同完成:
- server向ui提供输出内容,ui部分一般使用xxxOutput类型函数产生的容器显示输出
- 服务器对数据的处理结果通过server中的output列表参数向ui传递
- server使用不同的函数捕获不同类型的输出数据,如文字用renderText、屏幕图像用renderPlot
2 output列表
shinyApp的server参数需要设置为一个“server函数”,这个函数最关键的三个参数是input、output和session,使用过程中它们似乎是顺序可调但名称不可变。探讨源代码过于复杂,这里只说一下和实际应用有关的一些内容。
还是上面的shiny程序,运行后查看页面的HTML代码会发现body中有下面两行内容:
<h1 id="tx" class="shiny-text-output"></h1> <div id="pl" class="shiny-plot-output" style="width: 100% ; height: 400px"></div>
第一行h1容器是textOutput函数产生的,而第二行的div容器是plotOutput产生的。只看见ui中设置的内容,而server提供(通过jQuery)的内容在代码上完全不可见。对于这两个容器(h1和div),应该注意的是它们的id和class属性。
- id属性与server中output列表项的名称/ID对应,即:如果ui中的某容器id是xx,server中相应部分是output$xx
- class属性与server中的render结果呈现类型对应,如shiny-text-output类容器对应renderText函数结果
如果把shinyApp中的内容替换为下面内容,程序完全可以正常运转,但是去掉id或class中的任何一项都不