I have a two-dimensional dataset with 100 observations. I used hexagonal binning and ended up with 26 hexagonal bins. To save lines of 100 cases that are in each of the 26 hexagons, I used the base::attr
function in R. In the code below, this is done with:
attr(hexdf, "cID") <- h@cID
I am trying to create an interactive R Plotly
object in a hexagon binary so that if the user had to click on this hexagonal box, they would get lines of 100 observations that were grouped into this bit. I have a part of this goal. My MWE is below:
library(plotly) library(data.table) library(GGally) library(hexbin) library(htmlwidgets) set.seed(1) bindata <- data.frame(ID = paste0("ID",1:100), A=rnorm(100), B=rnorm(100)) bindata$ID <- as.character(bindata$ID) x = bindata[,c("A")] y = bindata[,c("B")] h <- hexbin(x=x, y=y, xbins=5, shape=1, IDs=TRUE) hexdf <- data.frame (hcell2xy (h), hexID = h@cell , counts = h@count ) attr(hexdf, "cID") <- h@cID pS <- ggplot(hexdf, aes(x=x, y=y, fill = counts, hexID=hexID)) + geom_hex(stat="identity") ggPS <- ggplotly(pS) myLength <- length(ggPS[["x"]][["data"]]) for (i in 1:myLength){ item =ggPS[["x"]][["data"]][[i]]$text[1] if (!is.null(item)) if (!startsWith(item, "co")){ ggPS[["x"]][["data"]][[i]]$hoverinfo <- "none" } } ggPS %>% onRender(" function(el, x, data) { //console.log(el) //console.log(x) //console.log(data) myGraph = document.getElementById(el.id); el.on('plotly_click', function(e) { cN = e.points[0].curveNumber split1 = (x.data[cN].text).split(' ') hexID = (x.data[cN].text).split(' ')[2] counts = split1[1].split('<')[0] console.log(hexID) console.log(counts) })} ", data = pS$data)
When I run this code and open it in a web browser, I get an interactive plot, as shown below (the green frame is not in the plot, it overlays for explanatory purposes):
If I click on the hexagon inside the green window, the correct hexID
of 40 and counts
of 3 are printed to the console. At this point, I would like to get 3 lines of the original data frame that were placed in this hexagon.
I know how to do this in R outside of the onRender()
function of the onRender()
package using the base::attr
function. For example, I can do the following:
hexID=40 obsns <- which(attr(pS$data, "cID")==hexID) dat <- bindata[obsns,]
And get the following correct 3 data points that were placed in this box that I clicked on:
ID AB 47 ID47 0.3645820 2.087167 66 ID66 0.1887923 2.206102 71 ID71 0.4755095 2.307978
I work with much larger datasets than in this MWE. For this reason, my intention to use the base:attr
function was to prevent an ever-increasing amount of data frame. However, I'm not sure how to translate the functionality of the base::attr
function so that I can access the corresponding rows of data that are found in the click of the hexagon in the onRender()
code. I have included the pS$data
object in the onRender()
code of JavaScript, but I am still stuck.
Any advice would be truly appreciated!