Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
920 views
in Technique[技术] by (71.8m points)

time series - "circular" mean in R

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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'

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...