Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add data to ggvis tooltip that's contained in the input dataset but not directly in the vis

Tags:

r

shiny

ggvis

This is my input dataset:

> names(breakingbad.episodes)
[1] "season"           "episode"          "epnum"            "epid"             "title"           
[6] "url.trakt"        "firstaired.utc"   "id.tvdb"          "rating"           "votes"           
[11] "loved"            "hated"            "overview"         "firstaired.posix" "year"            
[16] "zrating.season"   "src"     

For my ggvis, I'm using the following variables firstaired.posix and rating:

> str(breakingbad.episodes[c("firstaired.posix", "rating")])
'data.frame':   62 obs. of  2 variables:
$ firstaired.posix: POSIXct, format: "2008-01-21 02:00:00" "2008-01-28 02:00:00" "2008-02-  11 02:00:00" ...
$ rating          : num  87 85 84 84 83 90 87 85 88 83 ...

I successfully created my ggvis with a tooltip containing the rating information like this:

> breakingbad.episodes %>% 
ggvis(x = ~firstaired.posix, 
    y = ~rating, 
    fill = ~season) %>% 
layer_points() %>%
add_axis("x", title = "Airdate") %>%
add_axis("y", title = "Rating") %>%
add_legend("fill", title = "Season") %>%
add_tooltip(function(data){paste0("Rating: ", data$rating)}, "hover")

But I actually want the tooltip to contain more data, like the epid variable, so I tried:

…
add_tooltip(function(data){paste0("Rating: ", data$rating, "\n", "Epid: ", as.character(data$epid))}, "hover")

…Using as.character() because epid is an ordered factor – But the part of the tooltip is empty. (I also noticed the linebreak I intended \n to insert is missing, but that's a different problem).

It looks like the cause of this problem is that the vis object created by piping my dataset into ggvis doesn't contain the information I want to display, at least that's why I gathered by looking through the output of str() on the first example.

EDIT: I solved that linebreak issue, so there's no need to point me to ?add_tooltip – totally forgot about that.

EDIT: The accepted answer is working fine, even though it doesn't let me put arbitrary variables in the tooltip, it's pretty much what I need for my usecase, thanks! Here's what I did in the end:

breakingbad.episodes <- transform(breakingbad.episodes, id = paste0(epid, " - ", title))

breakingbad.episodes %>% 
  ggvis(x = ~firstaired.posix, 
      y = ~rating, 
      fill = ~season, 
      key := ~id) %>% 
  layer_points() %>%
  add_axis("x", title = "Airdate") %>%
  add_axis("y", title = "Rating") %>%
  add_legend("fill", title = "Season") %>%
  add_tooltip(all_values, "click")
like image 627
Jemus42 Avatar asked Jul 01 '14 22:07

Jemus42


2 Answers

Yes, it's possible. Normally the client only sends back the columns of data that are actually in the plot. To get other columns, you should use a key to index into the original data: This is simple reproducible example

library(ggvis)
mtc <- mtcars
mtc$id <- 1:nrow(mtc)

all_values <- function(x) {
  if(is.null(x)) return(NULL)
  row <- mtc[mtc$id == x$id, ]
  paste0(names(row), ": ", format(row), collapse = "<br />")
}

mtc %>% ggvis(x = ~wt, y = ~mpg, key := ~id) %>%
  layer_points() %>%
  add_tooltip(all_values, "hover")
like image 168
Koundy Avatar answered Nov 09 '22 09:11

Koundy


One workaround is to pass the epid variable in the key property, which is normally meant to keep track of which observations correspond to one another during transitions but it has the desired effect here of including epid in the data without producing any side effects:

breakingbad.episodes <- data.frame(firstaired.posix = as.POSIXct(c("2008-01-21 02:00:00", "2008-01-28 02:00:00")),
rating = c(87, 85), epid = as.factor(c(12,23)), season = as.factor(c(1,2)), somevar = c("special", "very_special"))

breakingbad.episodes %>% 
  ggvis(x = ~firstaired.posix, 
        y = ~rating, 
        fill = ~season, key := ~epid) %>% 
  layer_points() %>%
  add_axis("x", title = "Airdate") %>%
  add_axis("y", title = "Rating") %>%
  add_legend("fill", title = "Season") %>%
  add_tooltip(function(data){paste0("Rating: ", data$rating, "\n", "Epid: ", as.character(data$epid))}, "hover")

If you needed to use multiple variable from the original dataset you can add an id column with a unique value for each row and then do this:

breakingbad.episodes <- data.frame(id = c(1,2), firstaired.posix = as.POSIXct(c("2008-01-21 02:00:00", "2008-01-28 02:00:00")),
rating = c(87, 85), epid = as.factor(c(12,23)), season = as.factor(c(1,2)), somevar = c("special", "very_special"))

breakingbad.episodes %>% 
  ggvis(x = ~firstaired.posix, 
        y = ~rating, 
        fill = ~season, key := ~id) %>% 
  layer_points() %>%
  add_axis("x", title = "Airdate") %>%
  add_axis("y", title = "Rating") %>%
  add_legend("fill", title = "Season") %>%
  add_tooltip(function(data){paste0("Rating: ", data$rating, "\n", "Epid: ",
as.character(breakingbad.episodes$epid[breakingbad.episodes$id == data$id]), "\n", 
"What this is: ", breakingbad.episodes$somevar[breakingbad.episodes$id == data$id])}, "hover")
like image 2
ecologician Avatar answered Nov 09 '22 10:11

ecologician