2016-03-28 2 views
4

У меня есть набор данных, где x представляет собой день года (скажем, дни рождения), и я хочу создать график плотности этого. Кроме того, поскольку у меня есть информация о группе (скажем, мальчики или девочки), я хочу использовать возможности ggplot2, чтобы сделать график плотности.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))) 

Однако это дает плохую оценку из-за краевые эффекты. Я хочу применить тот факт, что я могу использовать круговые координаты, чтобы 365 + 1 = 1 - один день после 31 декабря - 1 января. Я знаю, что пакет circular предоставляет эту функциональность, но я не успел его реализовать, используя вызов stat_function(). Это особенно полезно для меня, чтобы использовать ggplot2, потому что я хочу, чтобы иметь возможность использовать грани, aes вызовов и т.д.

Кроме того, для уточнения, я хотел бы что-то, что выглядит как geom_density - Я не ищу полярное как показано на рисунке: Circular density plot using ggplot2.

+0

Это [очень аккуратным пример] (HTTP: // StackOverflow .com/q/13887365/2572423), которые могут быть полезны и пытаются показать это как круговую карту тепла, а не плотности. – JasonAizkalns

ответ

7

Чтобы удалить краевые эффекты, вы можете складывать три копии данных, создавать оценку плотности, а затем показывать плотность только для средней копии данных. Это гарантирует «обертывание» непрерывности функции плотности от одного края к другому.

Ниже приведен пример сравнения исходного участка с новой версией. Я использовал параметр 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") 

enter image description here

+0

Решает мою проблему - почти контр-интуитивно просто. – mbarete