Mam dwuwymiarowy zbiór danych zawierający 100 obserwacji. Użyłem sześciokąta binningowego i skończyłem z 26 sześciokątnymi pojemnikami. W celu zaoszczędzenia rzędy 100 uwag, które są w każdym z pojemników sześciokąt 26, użyłem funkcji base::attr
w R. W poniższym kodzie, to odbywa się pod adresem:Pobieranie atrybutów obiektów R w JavaScript
attr(hexdf, "cID") <- [email protected]
Próbuję utworzyć interaktywny obiekt R Plotly
binningu sześciokątnego tak, że jeśli użytkownik kliknie na dany pojemnik z sześciokątem, otrzyma rzędy 100 obserwacji, które zostały zgrupowane w tym pojemniku. Mam część tego celu ukończoną. Moja MWE jest poniżej:
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 = [email protected], counts = [email protected])
attr(hexdf, "cID") <- [email protected]
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)
Kiedy uruchomić ten kod i otworzyć go w przeglądarce internetowej, mogę otrzymać interaktywny wykres jak poniżej (zielone pole nie jest w działce; to nałożony do celów informacyjnych):
Gdybym kliknij na sześciokąt w środku zielonego pola, prawidłowa hexID
40 i counts
z 3 są wypisywane na konsoli. W tym momencie chciałbym uzyskać 3 wiersze oryginalnej ramki danych, które zostały umieszczone w tym sześciokątnym pojemniku.
wiem, jak to zrobić w R poza funkcją onRender()
pakietu htmlwidgets
za pomocą funkcji base::attr
. Na przykład, można wykonać następujące czynności:
hexID=40
obsns <- which(attr(pS$data, "cID")==hexID)
dat <- bindata[obsns,]
i odbierać następujące poprawnych 3 punkty danych, które zostały wprowadzone w tym pojemniku Kliknąłem na:
ID A B
47 ID47 0.3645820 2.087167
66 ID66 0.1887923 2.206102
71 ID71 0.4755095 2.307978
pracuję z dużo większych zbiorów danych niż w ten MWE. Z tego powodu, moim zamiarem użycia funkcji base:attr
było zapobieganie przemieszczaniu się coraz większej ramki danych. Nie jestem jednak pewien, jak przetłumaczyć funkcję funkcji base::attr
, aby uzyskać dostęp do odpowiednich wierszy punktów danych, które występują w klikniętym koszu sześciokątnym w kodzie JavaScript onRender()
. Dodałem obiekt pS$data
do kodu JavaScript , ale nadal mam problem.
Każda rada byłaby szczerze doceniona!
Dziękuję za pomoc! Zdaję sobie sprawę, że brakowało mi przewidywania i nadmiernego uproszczenia mojego MWE, więc istnieje rozwiązanie (jak pokazałeś), które nie wymaga użycia base :: attr(). Rozwiązanie może być nadal pomocne dla mnie i innych osób. Napisałem lepszy MWE, który, mam nadzieję, ukazuje wyraźniej, dlaczego wciąż czuję się zablokowany przez bazę :: attr() i dlaczego nie sądzę, aby rozwiązanie tutaj działało w tym przypadku. Opublikowalem to w wersji 2 (http://stackoverflow.com/questions/42460061/retrieving-r-object-attributes-in-javascript-part-2). Dziękuję Ci. – luckButtered
Mam coś, co ta sama strategia będzie działać dla części 2, napisałem rozwiązanie, które z nadzieją działa na twoim pełnym przykładzie. – NicE