我之前发布了类似的问题(Retrieving R object attributes in JavaScript)。在那篇较早的文章中,我简单地介绍了我的MWE,所以不幸的回答并不真正适用于我真正的问题。在这里,我展示了为什么我需要在JavaScript中检索R对象属性(除非有另一个我不知道的选项)。在JavaScript中检索R对象属性 - 第2部分
我有一个包含100个观测值的5变量数据集。我使用六边形装箱并创建了散点图矩阵。 10个散点图中的每一个都有12-18个六边形之间的地方。
attr(hexdf, "cID") <- [email protected]
:为了节省100组的意见,即在每个六边形仓所有10个散点图的行,我使用的碱::在R. ATTR功能在下面的代码,这是在完成
我正在尝试创建六边形装箱的交互R Plotly对象,以便如果用户点击给定的六角仓(无论哪个散点图),它们将获得分组为该仓的100个观测值的行。我完成了这个目标的一部分。我MWE低于:
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 = [email protected], counts = [email protected])
attr(hexdf, "cID") <- [email protected]
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)
这将创建一个图像,如下图所示:
举个例子,如果我点击六边形绿色框中突出,我可以确定哪些插曲它出现在(“myX”和“myY”)中,单击的六边形的标识(“hexID”)以及被分类到该六边形中的观察点的数量(“计数”)。对于这个特定的六边形,myX = 5,myY = 2,hexID = 39,计数= 1。因此,用户只需在第五行和第二列散点图上点击带ID39的六角形,并且应该有一个数据点归档。
如果我离开的OnRender()函数,并且简单地键入成R以下代码:
myX <- 5
myY <- 2
hexID <- 39
obsns <- which(attr(pS[myX,myY]$data, "cID")==hexID)
dat <- bindata[obsns,]
然后,我可以获取包含该一个观察结果被分级成数据帧的行点击六边形:
> dat
ID A B C D E
95 ID95 1.586833 -1.208083 1.778429 -0.1101588 3.810277
我的问题只是在最后一步。我无法弄清楚如何使用onRender()函数中的base :: attr()函数来获取“obsns”对象。有没有解决这个问题的办法,或者我应该考虑采取另一种可能的方法?感谢您的任何想法/建议!
谢谢你向我指出这一点。我一直在研究这个问题很长一段时间,而且我从来没有想过我可以用你的演示方式来使用attr(),即使在你之前将它显示为一个子场景之后。令我惊讶的是,这种方法似乎不会在onRender()函数中造成延迟。我将数据框大小从100个例子改为50,000个,当我点击给定的六边形时,它可以立即解析50,000个大数据框以获得单独的观察结果。我认为JavaScript允许这发生得比我预期的更快(我大多使用R)? – luckButtered