I posted a similar question earlier ( Extracting attributes of an R object in JavaScript ). In this earlier post, I simplified my MWE, and so the answer I received, unfortunately, does not really apply to my real problem. Here I show why I might need to get the attributes of an R object in JavaScript (if there is no other option that I don't know about).
I have a 5 variable dataset with 100 observations. I used a hexagon and created a diffused screen matrix. Each of the 10 scatterplots has somewhere between 12-18 hexagons. To save lines of 100 observations that are in each of the hexagons for all 10 scatterplots, 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 a user clicks on a given hexagon (no matter what the scatter graph is), they will get lines of 100 observations that were grouped into this bin. 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), C=rnorm(100), D=rnorm(100), E=rnorm(100)) bindata$ID <- as.character(bindata$ID) maxVal = max(abs(bindata[,2:6])) maxRange = c(-1*maxVal, maxVal) my_fn <- function(data, mapping, ...){ x = data[,c(as.character(mapping$x))] y = data[,c(as.character(mapping$y))] h <- hexbin(x=x, y=y, xbins=5, shape=1, IDs=TRUE, xbnds=maxRange, ybnds=maxRange) hexdf <- data.frame (hcell2xy (h), hexID = h@cell , counts = h@count ) attr(hexdf, "cID") <- h@cID p <- ggplot(hexdf, aes(x=x, y=y, fill = counts, hexID=hexID)) + geom_hex(stat="identity") p } p <- ggpairs(bindata[,2:6], lower = list(continuous = my_fn)) pS <- p for(i in 2:p$nrow) { for(j in 1:(i-1)) { pS[i,j] <- p[i,j] + coord_cartesian(xlim = c(maxRange[1], maxRange[2]), ylim = c(maxRange[1], maxRange[2])) } } 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) { el = el; x=x; var data = data[0]; console.log(el) console.log(x) console.log(data) myLength = Math.sqrt(document.getElementsByClassName('cartesianlayer')[0].childNodes.length); console.log(myLength) el.on('plotly_click', function(e) { console.log(e.points[0]) xVar = (e.points[0].xaxis._id).replace(/[^0-9]/g,'') if (xVar.length == 0) xVar = 1 yVar = (e.points[0].yaxis._id).replace(/[^0-9]/g,'') if (yVar.length == 0) yVar = 1 myX = myLength + 1 - (yVar - myLength * (xVar - 1)) myY = xVar 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(myX) console.log(myY) console.log(hexID) console.log(counts) })} ", data = pS[5,2]$data)
This creates an image as shown below:
As an example, if I click on the hexagon highlighted in the green field, I can determine in which subheading it occurred ("myX" and "myY"), the hexagon click identifier ("hexID") and the number of observation points that were cut out into this hexagon ("considered"). For this particular hexagon, myX = 5, myY = 2, hexID = 39, and counts = 1. Thus, the user simply clicked on the hexagon with ID39 in the scatter chart on the fifth row and second column, and there should be 1 data point that he coded.
If I left the onRender () function and just typing in R the following code:
myX <- 5 myY <- 2 hexID <- 39 obsns <- which(attr(pS[myX,myY]$data, "cID")==hexID) dat <- bindata[obsns,]
Then I can get a data frame row containing one case that has been encoded into this hexagon:
> dat ID ABCDE 95 ID95 1.586833 -1.208083 1.778429 -0.1101588 3.810277
My problem is simply at this last step. I cannot figure out how to use the base :: attr () function from within the onRender () function to get the "obsns" object. Is there any workaround for this problem or another possible approach that I should consider? Thanks for any ideas / tips!