Eksperymentuję ze sposobami radzenia sobie z overplottingiem w R, a jedną rzeczą, którą chcę spróbować, jest wyrysowanie poszczególnych punktów, ale zabarwienie ich gęstością ich sąsiedztwa. W tym celu musiałbym obliczyć oszacowanie gęstości jądra 2D w każdym punkcie. Wydaje się jednak, że standardowe funkcje estymacji gęstości jądra są oparte na siatce. Czy istnieje funkcja obliczania oszacowań gęstości jądra 2D w określonych punktach, które określam? Wyobrażam sobie funkcję, która pobiera wektory x i y jako argumenty i zwraca wektor oszacowań gęstości.Jak mogę uzyskać wartość oszacowania gęstości jądra w określonych punktach?
Odpowiedz
W końcu znalazłem dokładną funkcję, której szukałem: interp.surface
z pakietu fields
. Z tekstu pomocy:
Wykorzystuje wagi dwuliniowe do interpolacji wartości na prostokątnej siatce do dowolnych lokalizacji lub do innej siatki.
Wiem, że to jest stare ... ale czy 'fields :: interp.surface' działa dla ciebie? To nie działa dla mnie z powyższym przykładem zabawek, ponieważ wymiary nie pasują do danych wyjściowych 'newdata' i' interp.surface'. Zobacz http://stackoverflow.com/questions/43896337/use-fieldsinterp-surface-to-interpolate-from-grid-to-irregular-points. – bstock
Jeśli dobrze rozumiem, co chcesz zrobić, może to zostać osiągnięte poprzez dopasowanie modelu wygładzania do oszacowania gęstości siatki, a następnie przy użyciu tego przewidzieć gęstość w każdym punkcie jesteś zainteresowany. Na przykład:
# Simulate some data and put in data frame DF
n <- 100
x <- rnorm(n)
y <- 3 + 2* x * rexp(n) + rnorm(n)
# add some outliers
y[sample(1:n,20)] <- rnorm(20,20,20)
DF <- data.frame(x,y)
# Calculate 2d density over a grid
library(MASS)
dens <- kde2d(x,y)
# create a new data frame of that 2d density grid
# (needs checking that I haven't stuffed up the order here of z?)
gr <- data.frame(with(dens, expand.grid(x,y)), as.vector(dens$z))
names(gr) <- c("xgr", "ygr", "zgr")
# Fit a model
mod <- loess(zgr~xgr*ygr, data=gr)
# Apply the model to the original data to estimate density at that point
DF$pointdens <- predict(mod, newdata=data.frame(xgr=x, ygr=y))
# Draw plot
library(ggplot2)
ggplot(DF, aes(x=x,y=y, color=pointdens)) + geom_point()
Lub jeśli po prostu zmienić n 10^6 otrzymujemy
Tak, dokładnie tego chciałem. Dzięki! –
W rzeczywistości model less może spowodować nadmierne wygładzenie wartości. Gęstość jądra już się wygładza. Czy istnieje sposób, aby po prostu zastosować dwuliniową (lub bikubiczną) interpolację z wartości siatki? –
Jeśli ostrożnie ustawisz parametr rozpiętości na lessowy na dość niską wartość, dostaniesz zachowanie, które chcesz, myślę. Mogą być też inne sposoby. –
Czy istnieje szczególny powód, dla którego mieszanie alpha lub bardziej standardowe metody binowania (takie jak binowanie heksagonalne) nie są wystarczające? – joran
Chcę, aby wartości odstające były wyraźnie widoczne jako pojedyncze punkty. Pękanie alfa sprawia, że wystające części są słabe, a sześciokątne binning zamienia je w całe sześciokąty zamiast pojedynczych punktów. Ocena gęstości jądra na całej siatce dobrze sprawdza się w przypadku większości danych, ale wszystkie punkty odstające zmieniają się w małe gaussowskie "pufy", więc chcę zamiast tego obliczyć oszacowanie gęstości jądra i użyć go do przypisania koloru do każdego punktu . W ten sposób uzyskalibyśmy w zasadzie taki sam wygląd, jak podejście oparte na siatce, gdzie wiele punktów nakłada się, ale spowodowałoby, że wartości odstające byłyby wyraźnie widoczne jako punkty dyskretne. –