Получение атрибутов R объекта в JavaScript

У меня есть двумерный набор данных со 100 наблюдениями. Я использовал шестиугольную корзину и в итоге получил 26 шестиугольных корзин. Чтобы сохранить строки из 100 наблюдений, которые находятся в каждой из 26 шестиугольных корзин, я использовал base::attr функция в R. В приведенном ниже коде это делается в:

attr(hexdf, "cID") <- h@cID

Я пытаюсь создать интерактивный 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))
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)

Когда я запускаю этот код и открываю его в веб-браузере, я получаю интерактивный график, как показано ниже (зеленое поле не в графике; оно накладывается в пояснительных целях):

Если я нажму на шестиугольник внутри зеленой рамки, правильный hexID из 40 и counts из 3 печатаются на консоль. На этом этапе я хотел бы получить 3 строки исходного фрейма данных, которые были помещены в этот шестиугольный контейнер.

Я знаю, как сделать это в R за пределами onRender() функция htmlwidgets пакет с помощью base::attr функция. Например, я могу сделать следующее:

hexID=40
obsns <- which(attr(pS$data, "cID")==hexID)
dat <- bindata[obsns,]

И получите следующие правильные 3 точки данных, которые были помещены в корзину, по которой я щелкнул:

     ID         A        B
47 ID47 0.3645820 2.087167
66 ID66 0.1887923 2.206102
71 ID71 0.4755095 2.307978

Я работаю с гораздо большими наборами данных, чем в этом MWE. По этой причине мое намерение использовать base:attr функция заключалась в том, чтобы не допускать, чтобы вокруг проплывало больше данных Тем не менее, я не уверен, как перевести функциональность base::attr функция, чтобы я мог получить доступ к соответствующим строкам точек данных, которые находятся в ячейке шестиугольника, по которой щелкают onRender() Код JavaScript Я включил pS$data возражать в onRender() Код JavaScript, но я все еще застрял.

Любой совет будет искренне признателен!

1 ответ

Решение

Вы можете добавить столбец, для каждой строки которого есть идентификатор гексбина, которому он принадлежит, в ваших привязках:

bindata$hex <- h@cID

Затем вы можете передать его onRender функционировать и фильтровать строки, когда пользователь нажимает на шестиугольник:

ggPS %>% onRender("
                  function(el, x, 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]

                  var selected_rows = [];

                  data.forEach(function(row){
                    if(row.hex==hexID) selected_rows.push(row);
                  });
                  console.log(selected_rows);

                  })}
                  ", data = bindata)
Другие вопросы по тегам