linked_brush 当数据更改时,ggvis 中的 Shiny 无法工作
linked_brush in ggvis cannot work in Shiny when data change
我想创建一个 Shiny APP,它使用 ggvis 绘制交互式图形,并在图形中 linked_brush 到 select 点。绘图数据根据输入更改。
但是当我尝试将所有内容放在一起时收到错误消息。
Error : Length of calculated column 'reactive_185425318' (0)
is not equal to 1 or the number of rows in data (32).
我尝试通过 ggvis 中的 "basic" 演示创建一个最小示例:
ui.R
library(ggvis)
shinyUI(pageWithSidebar(
div(),
sidebarPanel(
textInput('filter', 'Filters', ''),
uiOutput("plot_ui")
),
mainPanel(
ggvisOutput("plot")
)
))
server.R
library(ggvis)
library(dplyr)
shinyServer(function(input, output, session) {
# A reactive subset of mtcars
mtc <- reactive({
mtcs <- mtcars %>%
mutate(name = row.names(.))
if (nchar(input$filter) > 0)
{
mtcs <- mtcs %>% filter(grepl(input$filter, name))
}
print(mtcs)
mtcs
})
lb <- linked_brush(keys = mtc()$id, "red")
mtc %>%
ggvis(~wt, ~mpg) %>%
layer_points(fill := lb$fill, fill.brush := 'red') %>%
lb$input() %>%
bind_shiny("plot", "plot_ui")
})
如果我改变
layer_points(fill := lb$fill, fill.brush := 'red') %>%
进入
layer_points() %>%
一切都对我有用。我想这个问题与 "linked_brush".
有关
我该如何解决这个问题?感谢您的任何建议。
我的会话信息:
sessionInfo()
R version 3.1.1 (2014-07-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_Australia.1252 LC_CTYPE=English_Australia.1252 LC_MONETARY=English_Australia.1252 LC_NUMERIC=C LC_TIME=English_Australia.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] stringr_0.6.2 magrittr_1.5 dplyr_0.4.1.9000 rproject_0.1.0.4509 ggvis_0.4.0.9000 shiny_0.11.1
loaded via a namespace (and not attached):
[1] assertthat_0.1.0.99 DBI_0.3.1 digest_0.6.4 htmltools_0.2.6 httpuv_1.3.2 lazyeval_0.1.10.9000 mime_0.2 parallel_3.1.1 R6_2.0.1
[10] Rcpp_0.11.3 RJSONIO_1.3-0 tools_3.1.1 xtable_1.7-4
改变
lb <- linked_brush(keys = mtc()$id, "red")
至:
lb <- linked_brush(keys = 1:nrow(mtcars), "red")
您要么需要 id
变量,要么像这样在函数中直接创建它。
编辑
正如@NicE 所指出的,我没有意识到过滤也是问题的一部分。请参阅此 gist 以获得可行的解决方案。
shiny::runGist("https://gist.github.com/cdeterman/fd6bf3955ef56fe9f38d")
虽然使 ggvis 图具有反应性并不是最有吸引力的解决方案,但我认为这是必要的。如果你不包括 scale_numeric
如果只有一个级别(例如过滤到马自达),情节将会崩溃。 scale_numeric
可以很好地设置轴的范围。要更改轴,我的印象是 ggvis 必须是反应式的。
我遇到了同样的问题。通过修改 linked_brush()
以包含用于设置键的函数来解决它。
从 ggvis 中的 linked_brush.R 修改了 linked_brush()
:
linked_brush <- function(keys, fill = "red") {
stopifnot(is.character(fill), length(fill) == 1)
rv <- shiny::reactiveValues(under_brush = character(), keys = character())
rv$keys <- isolate(keys)
input <- function(vis) {
handle_brush(vis, fill = fill, on_move = function(items, ...) {
rv$under_brush <- items$key__
})
}
set_keys <- function(keys) {
rv$keys <- keys
}
set_brush <- function(ids) {
rv$under_brush <- ids
}
selected_r <- reactive(rv$keys %in% rv$under_brush)
fill_r <- reactive(c("black", fill)[selected_r() + 1])
list(
input = input,
selected = create_broker(selected_r),
fill = create_broker(fill_r),
set_keys = set_keys,
set_brush = set_brush
)
}
现在,您的示例中的 server.R 可以修改为在 mtcs
更改时设置键:
library(ggvis)
library(dplyr)
shinyServer(function(input, output, session) {
lb <- linked_brush(keys = NULL, "red")
# A reactive subset of mtcars
mtc <- reactive({
mtcs <- mtcars %>%
mutate(name = row.names(.))
if (nchar(input$filter) > 0)
{
mtcs <- mtcs %>% filter(grepl(input$filter, name))
}
print(mtcs)
lb$set_keys(seq_len(nrow(mtcs)))
mtcs
})
mtc %>%
ggvis(~wt, ~mpg) %>%
layer_points(fill := lb$fill, fill.brush := 'red') %>%
lb$input() %>%
bind_shiny("plot", "plot_ui")
})
我想创建一个 Shiny APP,它使用 ggvis 绘制交互式图形,并在图形中 linked_brush 到 select 点。绘图数据根据输入更改。
但是当我尝试将所有内容放在一起时收到错误消息。
Error : Length of calculated column 'reactive_185425318' (0)
is not equal to 1 or the number of rows in data (32).
我尝试通过 ggvis 中的 "basic" 演示创建一个最小示例:
ui.R
library(ggvis)
shinyUI(pageWithSidebar(
div(),
sidebarPanel(
textInput('filter', 'Filters', ''),
uiOutput("plot_ui")
),
mainPanel(
ggvisOutput("plot")
)
))
server.R
library(ggvis)
library(dplyr)
shinyServer(function(input, output, session) {
# A reactive subset of mtcars
mtc <- reactive({
mtcs <- mtcars %>%
mutate(name = row.names(.))
if (nchar(input$filter) > 0)
{
mtcs <- mtcs %>% filter(grepl(input$filter, name))
}
print(mtcs)
mtcs
})
lb <- linked_brush(keys = mtc()$id, "red")
mtc %>%
ggvis(~wt, ~mpg) %>%
layer_points(fill := lb$fill, fill.brush := 'red') %>%
lb$input() %>%
bind_shiny("plot", "plot_ui")
})
如果我改变
layer_points(fill := lb$fill, fill.brush := 'red') %>%
进入
layer_points() %>%
一切都对我有用。我想这个问题与 "linked_brush".
有关我该如何解决这个问题?感谢您的任何建议。
我的会话信息:
sessionInfo()
R version 3.1.1 (2014-07-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_Australia.1252 LC_CTYPE=English_Australia.1252 LC_MONETARY=English_Australia.1252 LC_NUMERIC=C LC_TIME=English_Australia.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] stringr_0.6.2 magrittr_1.5 dplyr_0.4.1.9000 rproject_0.1.0.4509 ggvis_0.4.0.9000 shiny_0.11.1
loaded via a namespace (and not attached):
[1] assertthat_0.1.0.99 DBI_0.3.1 digest_0.6.4 htmltools_0.2.6 httpuv_1.3.2 lazyeval_0.1.10.9000 mime_0.2 parallel_3.1.1 R6_2.0.1
[10] Rcpp_0.11.3 RJSONIO_1.3-0 tools_3.1.1 xtable_1.7-4
改变
lb <- linked_brush(keys = mtc()$id, "red")
至:
lb <- linked_brush(keys = 1:nrow(mtcars), "red")
您要么需要 id
变量,要么像这样在函数中直接创建它。
编辑
正如@NicE 所指出的,我没有意识到过滤也是问题的一部分。请参阅此 gist 以获得可行的解决方案。
shiny::runGist("https://gist.github.com/cdeterman/fd6bf3955ef56fe9f38d")
虽然使 ggvis 图具有反应性并不是最有吸引力的解决方案,但我认为这是必要的。如果你不包括 scale_numeric
如果只有一个级别(例如过滤到马自达),情节将会崩溃。 scale_numeric
可以很好地设置轴的范围。要更改轴,我的印象是 ggvis 必须是反应式的。
我遇到了同样的问题。通过修改 linked_brush()
以包含用于设置键的函数来解决它。
从 ggvis 中的 linked_brush.R 修改了 linked_brush()
:
linked_brush <- function(keys, fill = "red") {
stopifnot(is.character(fill), length(fill) == 1)
rv <- shiny::reactiveValues(under_brush = character(), keys = character())
rv$keys <- isolate(keys)
input <- function(vis) {
handle_brush(vis, fill = fill, on_move = function(items, ...) {
rv$under_brush <- items$key__
})
}
set_keys <- function(keys) {
rv$keys <- keys
}
set_brush <- function(ids) {
rv$under_brush <- ids
}
selected_r <- reactive(rv$keys %in% rv$under_brush)
fill_r <- reactive(c("black", fill)[selected_r() + 1])
list(
input = input,
selected = create_broker(selected_r),
fill = create_broker(fill_r),
set_keys = set_keys,
set_brush = set_brush
)
}
现在,您的示例中的 server.R 可以修改为在 mtcs
更改时设置键:
library(ggvis)
library(dplyr)
shinyServer(function(input, output, session) {
lb <- linked_brush(keys = NULL, "red")
# A reactive subset of mtcars
mtc <- reactive({
mtcs <- mtcars %>%
mutate(name = row.names(.))
if (nchar(input$filter) > 0)
{
mtcs <- mtcs %>% filter(grepl(input$filter, name))
}
print(mtcs)
lb$set_keys(seq_len(nrow(mtcs)))
mtcs
})
mtc %>%
ggvis(~wt, ~mpg) %>%
layer_points(fill := lb$fill, fill.brush := 'red') %>%
lb$input() %>%
bind_shiny("plot", "plot_ui")
})