R:核密度图(带宽必须严格为正)

R: Kernel Density Plots (Bandwidth Must be Strictly Positive)

我正在使用 R 编程语言。我正在按照这里的教程在 R 中制作 3d 核密度图:https://plotly.com/r/3d-surface-plots/:

library(MASS)
library(plotly)

kd <- with(MASS::geyser, MASS::kde2d(duration, waiting, n = 50))
fig <- plot_ly(x = kd$x, y = kd$y, z = kd$z) %>% add_surface()

fig

我决定用我自己的数据试试这个:

#generate data
a = rnorm(100,10,10)
b = rnorm(100,5,5)
c = rnorm(100,5,10)
d = data.frame(a,b,c)

#make 3d plot (I think n = 50 refers to selecting the first 50 points?)
kd <- with(d, MASS::kde2d(a,b,c, n = 50))
fig <- plot_ly(x = kd$x, y = kd$y, z = kd$z) %>% add_surface()

但这会导致以下错误:

Error in MASS::kde2d(a, b, c, n = 50) : 
  bandwidths must be strictly positive

此错误阻止我创建“kd”对象。

有人可以告诉我我做错了什么吗?我使用的具体数据有问题吗?或者这是一个语法错误?

谢谢

您似乎误解了 kde2d 的目的。来自 help(kde2d):

Two-dimensional kernel density estimation with an axis-aligned bivariate normal kernel, evaluated on a square grid.

来自关于 h 参数的同一个帮助文件:

h
vector of bandwidths for x and y directions. Defaults to normal reference bandwidth (see bandwidth.nrd). A scalar value will be taken to apply to both directions.

您正在传递 c,一个长度为 100 的数值向量作为 h。您似乎在尝试将数据传递给 h,这没有意义。传递一个或两个带宽值或什么都不传递并接受默认值。

source 的第 31 行和第 32 行,我们可以看出您出现错误的原因:

    if (any(h <= 0))
        stop("bandwidths must be strictly positive")

因此,如果 c 的前两个值中的任何一个为负数或零,您将收到此错误。


n参数,如帮助文件所述:

n
Number of grid points in each direction. Can be scalar or a length-2 integer vector.

这决定了提供密度的网格。如果您提供单个值,则会生成方形网格。