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

问题描述

我使用的是 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,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,c,z = kd$z) %>% add_surface()

但这会导致以下错误

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

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

谁能告诉我我做错了什么?我使用的特定数据有问题吗?或者这是一个语法错误

谢谢

解决方法

您似乎误解了 kde2d 的用途。来自help(kde2d)

使用轴对齐的二元正态核进行二维核密度估计,在方形网格上进行评估。

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

h
x 和 y 方向的带宽向量。默认为正常参考带宽(参见bandwidth.nrd)。将采用标量值应用于两个方向。

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

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

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

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


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

n
每个方向的网格点数。可以是标量或长度为 2 的整数向量。

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