反应式Shiny表达式中的数据如何传递到ggvis图?

10

我正在熟悉ggvis,并尝试在shiny中使用它。我不太理解ggvis如何从响应式的Shiny表达式中获取数据。以下是来自ggvis GitHub存储库的基本应用程序:

ui.R:

shinyUI(pageWithSidebar(
  div(),
  sidebarPanel(
    sliderInput("n", "Number of points", min = 1, max = nrow(mtcars),
                value = 10, step = 1),
    uiOutput("plot_ui")
  ),
  mainPanel(
    ggvisOutput("plot"),
    tableOutput("mtc_table")
  )
))

服务器端代码(server.R):

library(ggvis)

shinyServer(function(input, output, session) {
  # A reactive subset of mtcars
  mtc <- reactive({ mtcars[1:input$n, ] })

  # A simple visualisation. In shiny apps, need to register observers
  # and tell shiny where to put the controls
  mtc %>%
    ggvis(~wt, ~mpg) %>%
    layer_points() %>%
    bind_shiny("plot", "plot_ui")

  output$mtc_table <- renderTable({
    mtc()[, c("wt", "mpg")]
  })
})
现在mtc是反应式表达式,实际上是一个函数(或者说它是吗?),其结果是一个数据框。然而,它被作为函数管道传递到了 ggvis 中。如果您尝试像这样传递结果数据框:
mtc() %>%  ggvis(~wt, ~mpg) %>%
layer_points() %>%
        bind_shiny("plot", "plot_ui")

Shiny会开始抱怨“没有活动的反应上下文不允许操作”。那么实际上正在发生什么?

我问这个问题的原因是我想返回额外的对象,我想在ggvis中使用它们。更准确地说,我想要更改x和y轴标签,其中标签在反应式表达式中计算,就像这样:

mtc <- reactive({ list(data=mtcars[1:input$n, ],
labx = "Computed x axis label",
laby = "Computed y axis label")
   })

mtc %>% ggvis(data=data,~wt,~mpg) %>% 
    layer_points() %>%
    add_axis("x",title=labx) %>%
    add_axis("y",title=laby) %>%
    bind_shiny("plot", "plot_ui")

有没有办法在 ggvis 调用中利用 mtc() 输出的结构?还是只能传递数据框并将数据放入数据框中?

或者还有另一种注册 ggvis 对象的方法吗?在这个问题中,ggvis 输出是通过 observe_ggvis 函数注册的,但似乎在当前的 ggvis 版本(0.3)中不存在该函数。

我正在使用 ggvis 0.3.0.1 和 shiny 0.10.0,R 版本为 3.1.1。

2个回答

18

在 ggvis 中可以通过“裸响应”将数据集传递给它。这样做时,当数据发生更改时,ggvis 将自动重新绘制数据,但不需要重新绘制整个图:

get_rct_df = reactive({  #code to change dataset from shiny input  )}
get_rct_df %>% ggvis() #rest of plotting code %>% bind_shiny("plot")
每当来自`get_rct_df`的数据发生更改时,这将更新绘图中的数据点(但不重新绘制整个图)。 这也意味着某些内容无法在不重新绘制整个图形的情况下更新(如绘图标签、`layer_model_predictions`方程式)。
您可以执行另一个建议并将整个图包装在反应式函数内:
reactive({
   get_rct_df %>% 
      ggvis() #rest of plotting code %>% 
      add_axis("x", title = input$title)
}) %>% bind_shiny("plot")

这将使您能够更新图的标题和其他部分。但这也会强制ggvis在发生更改时重新绘制整个图,而不仅仅是重新绘制数据。如果您尝试使用两种方法进行测试,方法1看起来会更“平滑”; ggvis具有内置的过渡动画,当您的数据发生变化时会自动播放。


4

好的,我在这个答案中找到了解决方案。

mtc <- reactive({ list(data=mtcars[1:input$n, ],
    labx = "Computed x axis label",
    laby = "Computed y axis label")
})

reactive({
    dl <- mtc()
    dl$data %>% ggvis(data=data,~wt,~mpg) %>% 
    layer_points() %>%
    add_axis("x",title=dl$labx) %>%
    add_axis("y",title=dl$laby) 
 }) %>% bind_shiny("plot", "plot_ui")

技巧在于调用响应式函数是被计算的,因此您可以将为 ggvis 计算数据和实际绘制 ggvis 的过程分开。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接