R ggplot2圆形数据的密度

R ggplot2圆形数据的密度,r,ggplot2,statistics,kernel-density,R,Ggplot2,Statistics,Kernel Density,我有一个数据集,x表示一年中的某一天(比如生日),我想创建一个密度图。 此外,由于我有一些分组信息(比如男孩或女孩),我想使用ggplot2的功能来绘制密度图 一开始很简单: require(ggplot2); require(dplyr) bdays <- data.frame(gender = sample(c('M', 'F'), 100, replace = T), bday = sample(1:365, 100, replace = T)) bdays %>% ggplo

我有一个数据集,
x
表示一年中的某一天(比如生日),我想创建一个密度图。 此外,由于我有一些分组信息(比如男孩或女孩),我想使用
ggplot2
的功能来绘制密度图

一开始很简单:

require(ggplot2); require(dplyr)
bdays <- data.frame(gender = sample(c('M', 'F'), 100, replace = T), bday = sample(1:365, 100, replace = T))
bdays %>% ggplot(aes(x = bday)) + geom_density(aes(color = factor(gender)))
require(ggplot2);需要(dplyr)
b天%ggplot(aes(x=b天))+几何密度(aes(颜色=系数(性别)))
然而,由于边缘效应,这给出了一个很差的估计。 我想应用这个事实,我可以使用圆坐标,这样365+1=1——12月31日后的一天是1月1日。 我知道
circular
包提供了这个功能,但是我还没有使用
stat\u function()
调用成功地实现它。 使用
ggplot2
对我来说特别有用,因为我希望能够使用facet、
aes
调用等


另外,为了澄清,我想要一个看起来像
geom_density
——我不是在寻找一个像所示的极坐标图。

要去除边缘效果,可以叠加三个数据副本,创建密度估计,然后只显示数据中间副本的密度。这将保证密度函数从一条边到另一条边的“环绕”连续性

下面是一个将原始绘图与新版本进行比较的示例。我使用了
adjust
参数来设置两个绘图之间的相同带宽。还请注意,在循环版本中,如果要将密度添加到1,则需要重新规范化密度:

set.seed(105)
bdays <- data.frame(gender = sample(c('M', 'F'), 100, replace = T), bday = sample(1:365, 100, replace = T))

# Stack three copies of the data, with adjusted values of bday
bdays = bind_rows(bdays, bdays, bdays)
bdays$bday = bdays$bday + rep(c(0,365,365*2),each=100)

# Function to adjust bandwidth of density plot
# Source: http://stackoverflow.com/a/24986121/496488
bw = function(b,x) b/bw.nrd0(x)

# New "circularized" version of plot
bdays %>% ggplot(aes(x = bday)) + 
  geom_density(aes(color = factor(gender)), adjust=bw(10, bdays$bday[1:100])) +
  coord_cartesian(xlim=c(365, 365+365+1), expand=0) +
  scale_x_continuous(breaks=seq(366+89, 366+365, 90), labels=seq(366+89, 366+365, 90)-365) +
  scale_y_continuous(limits=c(0,0.0016))
  ggtitle("Circularized")

# Original plot
ggplot(bdays[1:100,], aes(x = bday)) + 
  geom_density(aes(color = factor(gender)), adjust=bw(30, bdays$bday[1:100])) +
  scale_x_continuous(breaks=seq(90,360,90), expand=c(0,0)) +
  ggtitle("Not Circularized")
set.seed(105)
b天%ggplot(aes(x=b天))+
几何密度(aes(颜色=系数(性别)),调整=bw(10,b天$b天[1:100]))+
坐标笛卡尔(xlim=c(365,365+365+1),展开=0)+
比例x连续(中断=顺序(366+89366+365,90),标签=顺序(366+89366+365,90)-365)+
刻度连续(限值=c(0,0.0016))
标题(已分发)
#原图
ggplot(b天[1:100],aes(x=b天))+
几何密度(aes(颜色=系数(性别)),调整=体重(30,b天$b天[1:100]))+
比例x连续(中断=顺序(90360,90),扩展=c(0,0))+
标题(“未分发”)

这是一个可能有用的方法,它试图将其显示为一个圆形热图,而不是密度。解决了我的问题-几乎与直觉相反简单。