R 使用ggvis显示信息
我正在使用ggvis图形开发一个闪亮的应用程序。我试图在鼠标移动到图形上的某个点上时显示信息。如果我使用R 使用ggvis显示信息,r,ggvis,R,Ggvis,我正在使用ggvis图形开发一个闪亮的应用程序。我试图在鼠标移动到图形上的某个点上时显示信息。如果我使用图层点,则有关特定点的数据将正确显示。但是,如果我使用图层条,则即使数据集未更改,也会显示值为NULL dfL %>% ggvis(x = ~time, y = ~amount) %>% layer_points() %>% add_tooltip(all_values, "hover") %>% bind_shiny("AnPlot", "AnPlot_ui")
图层点
,则有关特定点的数据将正确显示。但是,如果我使用图层条
,则即使数据集未更改,也会显示值为NULL
dfL %>% ggvis(x = ~time, y = ~amount) %>% layer_points()
%>% add_tooltip(all_values, "hover") %>% bind_shiny("AnPlot", "AnPlot_ui")
^信息显示正确
dfL %>% ggvis(x = ~time, y = ~amount) %>% layer_bars(width=1, fill:= "white")
%>% add_tooltip(all_values, "hover") %>% bind_shiny("AnPlot", "AnPlot_ui")
^接收空值
以下是所有值的代码
all_values <- function(x) {
if(is.null(x)) return(NULL)
paste0("Amount: ", format(x$amount, digits=4),
" Present Value: ", format(x$pv, digits=4), collapse = "<br />")
}
all_value这是一个棘手的问题,因为不幸的是,并非所有类型的图层
s都能像图层点
那样很好地处理添加工具提示
。我对许多ggvis
函数的所有实现细节都不是100%清楚,但我至少会让您了解我对它的理解,以便您了解我是如何得出解决方案的。我将使用cars
数据集(默认情况下,该数据集应在您的会话中可用)进行演示,但您只需进行一些小的调整,即可将该方法应用于您自己的数据
library(dplyr)
library(ggvis)
##
my_data <- cars %>%
group_by(speed) %>%
summarize(avg_dist = mean(dist))
##
R> my_data
Source: local data frame [19 x 2]
speed avg_dist
1 4 6.00000
2 7 13.00000
3 8 16.00000
4 9 10.00000
5 10 26.00000
6 11 22.50000
7 12 21.50000
8 13 35.00000
9 14 50.50000
10 15 33.33333
11 16 36.00000
12 17 40.66667
13 18 64.50000
14 19 50.00000
15 20 50.40000
16 22 66.00000
17 23 54.00000
18 24 93.75000
19 25 85.00000
从add_tooltip
的内部打印出名称是一个很好的方法,可以准确地了解传递的数据。对于点_obj
,我们有:
point_obj %>% add_tooltip(vis_names,"hover")
这是我输入数据的列名。另一方面,对bar_obj
执行此操作将为我们提供:
bar_obj %>% add_tooltip(vis_names,"hover")
绝对不是my\u data
中的列名。如果我们定义另一个函数
bar_info <- function(x) {
if(is.null(x)) return(NULL)
paste(
names(x)[1],
x[1,1],
names(x)[2],
x[1,2],
names(x)[3],
x[1,3],
names(x)[4],
x[1,4],
sep=" : ",
collapse="<br />")
}
因此xmin_
和xmax_
显然是我们悬停的给定条的x坐标,而stack\u upr\u
和stack\u lwr\u
是各自的y坐标。从这里开始,我们只需要一种将条形坐标转换回原始输入数据的方法,my_data
在ggplot2
中,我经常使用一个整洁的函数,名为ggplot\u build
。当您在ggplot
对象上调用此函数时,它会创建打印(就像打印通常所做的那样),但也会返回有关构建打印的所有内容的详细信息—长轴范围、短轴范围等。。。当您需要查找有关图形的非常精确的信息时,这非常有用。我怀疑ggvis
会有类似于ggplot\u build
的功能,通过这个小插曲,我找到了函数get\u data
。在ggvis
对象上调用此函数将返回data.frame
s列表,其中第一个元素是原始的data.frame
(my_data
),第四个元素是data.frame
,其中包含上面条形图中显示的四列-xmin
,xmax
,stack\u upr\uu
和stack\u lwr\uu
从这里,我将定义一个最终函数,该函数将被传递到add\u tooltip
,用于bar\u obj
:
tooltip_bars <- function(x) {
if(is.null(x)) return(NULL)
bar_obj <- get("bar_obj",.GlobalEnv)
input_data <- get_data(bar_obj)[[1]]
bar_data <- get_data(bar_obj)[[4]]
xmin_col <- bar_data[,3]
row_idx <- which.min(abs(x[1,1]-xmin_col))
paste0(
paste0(names(input_data)[1],
": ",
format(input_data[row_idx,1],4)),
paste0(names(input_data)[2],
": ",
format(input_data[row_idx,2],4)),
collapse = "<br />")
}
从全局环境中获取实际绘制的ggvis
对象的副本,并将其拉入工具提示子功能的范围。接下来的两行
input_data <- get_data(bar_obj)[[1]]
bar_data <- get_data(bar_obj)[[4]]
对于本例,可能有一种更简单的方法将我们的值x[1,1]
与列xmin\uu
进行比较,以确定当前悬停的数据行。我使用了上面的which.min(…)
方法,因为我认为在这种情况下,xmin\uu
值不完全是某个整数+0.5的情况下,它会更加健壮。尝试测试浮点数之间的精确相等有时可能会有问题
无论如何,我们可以使用我们创建的row\u idx
来提取由我们悬停在上面的条表示的原始数据行(即x
包含的内容),这是在paste0(…)
部分完成的。结果如下所示:
bar_obj %>% add_tooltip(tooltip_bars,"hover")
由于某些原因,标签格式不正确;虽然这与我使用的一般方法无关
回到您最初的问题,关于为什么显示NULL
值,简短的回答是在层中传递给add\u工具提示的数据对象与在层条中传递给它的数据对象不同,因此调用x$amount
和x$pv
将返回NULL
,因为这些列在x
中不存在
为了澄清这一点,要将此代码应用于您自己的数据,请确保您创建了一个基本的ggvis
对象,就像我使用bar\u obj
一样,并在get(“bar\u obj,.GlobalEnv)
工具提示栏
函数的行中使用了它的名称。我遇到了类似的问题。我通过显式过滤悬停所属行的数据集来解决此问题,如:
my_tooltip <- function(x) {
# do some checks
if (is.null(x)) return(NULL)
if (is.null(x$bin)) return(NULL)
# select the data for the bar you're hovered over
all_data <- my.data()
this_data <- all_data[all_data$bin == x$bin, ]
paste0("<b>", this_data$bin, ": ", "</b><br>", format(this_data$value))
}
在我的示例中,从中不清楚是否需要键入bin
,因为它是绘图中的数据片段之一。但是,我发现如果没有明确设置该参数,工具提示将不会出现。谢谢您的详细回答。然而,我在实现它时遇到了一些问题。我创建了一个基本的ggvis
对象:layer\u条(x=~time,y=~pv,fill:=“#b0b0”)
。然后我更新了工具提示栏
:工具提示栏%bind\u闪亮(“AnPlot”、“AnPlot\u ui”)
。当我运行应用程序时,图形显示,但当我悬停时,我收到此错误警告:在observer:object'levelAn_obj'中未找到未处理的错误
。谢谢你的帮助!更正,我看到我没有完全复制上述评论中的对象。ggvis
对象是levelAn\u obj%ggvis(x=~time,y=~amount)%%>%layer\u bars()%%>%layer\u bars(x=~tim
input_data <- get_data(bar_obj)[[1]]
bar_data <- get_data(bar_obj)[[4]]
row_idx <- which.min(abs(x[1,1]-xmin_col))
bar_obj %>% add_tooltip(tooltip_bars,"hover")
my_tooltip <- function(x) {
# do some checks
if (is.null(x)) return(NULL)
if (is.null(x$bin)) return(NULL)
# select the data for the bar you're hovered over
all_data <- my.data()
this_data <- all_data[all_data$bin == x$bin, ]
paste0("<b>", this_data$bin, ": ", "</b><br>", format(this_data$value))
}
my_data <- reactive({
df <- df.all # simplest example
df <- df.all[df.all$group==input$selected_group,] # example using user input
})
vis <- reactive({
plot.data %>%
ggvis(x=~bin, y=~value, key := ~bin) %>% # key on `bin` here
layer_bars(width=1, fill=~group) %>%
add_tooltip(my_tooltip, "hover")
})
vis %>% bind_shiny("my_plot") # bind with UI name