generic_user - 4 years ago 122

R Question

Given a dataset of months, how do I calculate the "average" month, taking into account that months are circular?

`months = c(1,1,1,2,3,5,7,9,11,12,12,12)`

mean(months)

## [1] 6.333333

In this dummy example, the mean should be in January or December. I see that there are packages for circular statistics, but I'm not sure whether they suit my needs here.

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

I think

```
months <- c(1,1,1,2,3,5,7,9,11,12,12,12)
library("CircStats")
conv <- 2*pi/12 ## months -> radians
```

Now convert from months to radians, compute the circular mean, and convert back to months. I'm subtracting 1 here assuming that January is at "0 radians"/12 o'clock ...

```
(res1 <- circ.mean(conv*(months-1))/conv)
```

The result is -0.3457. You might want:

```
(res1 + 12) %% 12
```

which gives 11.65, i.e. partway through December (since we are still on the 0=January, 11=December scale)

I *think* this is right but haven't checked it too carefully.

For what it's worth, the `CircStats::circ.mean`

function is very simple -- it might not be worth the overhead of loading the package if this is all you need:

```
function (x)
{
sinr <- sum(sin(x))
cosr <- sum(cos(x))
circmean <- atan2(sinr, cosr)
circmean
}
```

Incorporating @A.Webb's clever alternative from the comments:

```
m <- mean(exp(conv*(months-1)*1i))
12+Arg(m)/conv%%12 ## 'direction', i.e. average month
Mod(m) ## 'intensity'
```

Recommended from our users: **Dynamic Network Monitoring from WhatsUp Gold from IPSwitch**. ** Free Download**