page under construction..... mind the ladders and wear your hard-hat if you're desperate. Or wait until this looks better.
Recommended reading: E. Batshelet (1914-1979) "Circular Statistics" (1981) (a few pages shared here)
Topics in the book include:
Pt. 1: Statistical tools.
1. Measures of location
2. Measures of dispersion, skewness, and kurtosis
3. Point estimation of parameters and fitting of distributions
4. Tests for randomness and goodness-of-fit
5. Confidence intervals
6. Two-sample and multisample tests
7. Bivariate methods
8. Periodic regression
9. Circular correlation
10. Second-order statistical analysis
11. Spherical distributions.
Pt. 2: Mathematical tools.
12. Essentials of plane geometry
13. Geometry of the ellipse
14. The bivariate normal distribution
15. Circular distributions
16. Moments of circular distributions
17. Maximum likelihood estimation.
SCRIPT:
#*******************************************************************
# Vector to Polar Coordinates
#*******************************************************************
#load your CSV file with your (x,y) coordinates
#what is my working directory?
getwd()
#change my working directory to the address that I have my csv files
setwd("C:/Users/Nicola/Desktop/Data analysis folders")
panorama = read.csv("antdata.csv")
panorama
x <- c (panorama$x)
x
y <- c(panorama$y)
y
# r = \sqrt{X*X + y*y}
# theta = atan2(y,x) <- returns data in RADIANS
theta = atan2(y,x)
theta
r = sqrt((x*x)+(y*y))
r
#combine each column into a single data frame, with theta in Radians
polardata=data.frame(theta, r)
polardata
# Your end goal: two columns "theta" (angle) and "r" (distance)"
# e.g.
fisherB20
#*******************************************************************
# Simple Analysis
#*******************************************************************
# LOAD the following packages: circular, CircStats
# converting the data set between degrees to radians
rad(x)
deg(x)
#____________________________________________________________________
# CIRCULAR VARIANCE: ranges from 0-1, where
#the following returns a dataframe with: n = sample size; r = resultant length; mean resultant length (rbar); circular variance (var= 1- r/n)
circ.disp(rad(x))
circ.disp(theta)
#____________________________________________________________________
#summary circular statistics: input data in radians
# 1. n = sample size
# 2. mean.dir = phi_bar (Batschelet 1.3.9)
# 3. rho = r (Batschelet 1.4) r ranges from 0-1, and in unimodal data, r=0 means data is spread out, r=1 all data in same direction
# *** INDEX OF STRAIGHTNESS: to measure how much of a path of a single animal deviates from a straight line(Emlen & Demong 1978)can use r (the mean vector length). If r is large (close to 1), the path is straight
circ.summary(theta)
# mean direction of vector x (phi_bar) in degrees
circ.mean(theta)
deg(circ.mean(theta))
#***************************************************************************************
# Rayleigh test: default is radians; returns the mean resultant length r.bar (test statistic) and the pvalue of the test
r.test(theta, degree=FALSE)
# or
rayleigh.test(theta) # this version is useful, because you can parse it to test a specified mean direction
#specifying a direction to test:
rayleigh.test(theta, mu= circular (60)) # where mu is a specified mean direction in an alternate hypothesis as a circular object
#***************************************************************************************
# Watson's Test on 2 samples of data
# x,y are vectors of circular data measured in radians
# alpha: significance level of test e.g. 0.01, 0.05. If you omit this argument, the p-value will be returned.
# suggest only to omit alpha if n>17
# null = there is no difference between the two samples
x <- circular(c(19, 11, 11, 20, -28, 20, 12, 17), units="degrees")
y <- circular(c(-30, -25, -20,-25), units= "degrees")
watson.two(rad(x),rad(y), alpha=0.05)
#***************************************************************************************
#Watson_Williams test: between several samples e.g. Batchelet/Duelli Wehner 1973 example
data <- list(
expt = circular(rep(c(-20, -10, 0), c(1,7,2)),
units="degrees", template="geographics"),
control = circular(rep(c(-10, 0, 10, 20), c(3,3,3,1)),
units="degrees", template="geographics")
)
watson.williams.test(data)
#***************************************************************************************
# GRAPHICS
rose.diag(theta, bins=20, main="", pts=FALSE, prop=1, cex=1, pch=16, shrink=1, col="#663399")
# unstacked circular plot
circ.plot(theta)
# stacked circular plot for single data set
circ.plot(theta, main= "title", pch=16, stack=TRUE, bins=20)
circ.plot(theta, main="", pch=16, stack=TRUE, bins=20, cex=1, dotsep=10, shrink=1)
#shrink changes the size of the plotted circle
#dotstep changes the distance between the stacked points; default = 40, decrease # for larger spaces
#************************************************************************
# Plotting multiple data sets on one polar plot
# with arrows
#************************************************************************
# The first data set will be plotted with black circles
# if you want to just add the angles and not load a big data set:
x <- circular(c(19, 11, 11, 20, -50, 20, 12, 17), units="degrees")
# theta is the set of angles in radians
x <- circular(c((deg(theta)), units="degrees")
#The mean of X is Z and will plot as a black arrow
z <-circular(c(98), units="degrees")
#________________________________________________________________________
# a hypothetical or reference direction, plotted as a green arrow
# e.g.y = fff-nest direction
y <- circular(c(0), units="degrees")
#________________________________________________________________________
# The second data (V) will be plotted with blue filled triangles
v <- circular(c(-30, -25, -20,-25), units= "degrees")
#The mean of V is W and will plot as blue arrow
w <- circular(c(-20), units= "degrees")
#_________________________________________________________________________
#Plotting script
plot(x, stack=FALSE,cex=1.25)
arrows.circular(y, x0 = 0, y0 = 0, na.rm = FALSE, shrink = 1, plot.info = NULL, zero = NULL, rotation = NULL, col= "green", lwd= 3)
arrows.circular(z, x0 = 0, y0 = 0, na.rm = FALSE, shrink = 1, plot.info = NULL, zero = NULL, rotation = NULL, col= "black",lwd= 3)
arrows.circular(w, x0 = 0, y0 = 0, na.rm = FALSE, shrink = 1, plot.info = NULL, zero = NULL, rotation = NULL, col= "blue", lwd= 3)
points((v), col= "blue", plot.info=res, pch=17, cex=1.25)
points((v), col= "blue", plot.info=res, pch=3, cex=1.25)
# in graphs colour is defined by parameter "col" NOT colour or color
#lwd is the width of a line
#cex is the size of the data point
#shrink: scales the arrow to the length of the circle radius
#pch = point shape
# 17 = triangle
# 18 = diamond .... etc
#____________________________________________________________________________