2013-04-24 1 views
11

Я экспериментирую с методами борьбы с overplotting в R, и одна вещь, которую я хочу попробовать, - это нарисовать отдельные точки, но покрасить их по плотности их окрестности. Для этого мне нужно было бы вычислить двумерную оценку плотности ядра в каждой точке. Однако, по-видимому, стандартные функции оценки плотности ядра основаны на сетке. Есть ли функция для вычисления оценок плотности ядра 2D в определенных точках, которые я указываю? Я бы представлял себе функцию, которая принимает векторы x и y в качестве аргументов и возвращает вектор оценок плотности.Как я могу получить значение оценки плотности ядра в определенных точках?

+0

Есть ли конкретная причина, почему альфа-смешивание или более стандартные подходы к биннингам (например, шестиугольное биннинг) недостаточны? – joran

+1

Я хочу, чтобы выбросы были четко видны как отдельные точки. Alpha belnding делает выбросы слабыми, а гексагональное биннинг превращает их в целые шестиугольники вместо отдельных точек. Оценка плотности ядра на всей сетке делает хорошую работу для большинства данных, но все точки выброса превращаются в небольшие гауссовские «затяжки», поэтому я хочу вместо этого вычислить оценку плотности ядра и использовать ее для назначения цвета каждой точке , Это создало бы по существу тот же вид, что и подход, основанный на сетке, где бы много точек не перекрывалось, но сделало бы выбросы очевидными как отдельные точки. –

ответ

4

В итоге я нашел точную функцию, которую я искал: interp.surface от fields. Из справочного текста:

Использует билинейные веса для интерполяции значений в прямоугольной сетке в произвольные местоположения или в другую сетку.

+1

Я знаю, что это старый ... но для вас работали 'fields :: interp.surface'? Это не работает для меня с приведенным выше примером игрушек, потому что размеры не совпадают между выводами 'newdata' и' interp.surface'. См. Http://stackoverflow.com/questions/43896337/use-fieldsinterp-surface-to-interpolate-from-grid-to-irregular-points. – bstock

5

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

# 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() 

enter image description here

Или, если я просто изменить п 10^6 мы получаем

enter image description here

+0

Да, это именно то, что я хотел. Благодаря! –

+0

На самом деле, модель лёсса может привести к чрезмерному сглаживанию значений. Плотность ядра уже делает сглаживание. Есть ли способ просто билинейной (или бикубической) интерполяции из значений сетки? –

+0

Если вы тщательно установите для параметра span значение leess до довольно низкого значения, вы получите поведение в значительной степени, что вы хотите, я думаю. Могут быть и другие способы. –