###
### Ramsay, Hooker & Graves (2009)
### Functional Data Analysis with R and Matlab (Springer)
###
# Remarks and disclaimers
# These R commands are either those in this book, or designed to
# otherwise illustrate how R can be used in the analysis of functional
# data.
# We do not claim to reproduce the results in the book exactly by these
# commands for various reasons, including:
# -- the analyses used to produce the book may not have been
# entirely correct, possibly due to coding and accuracy issues
# in the functions themselves
# -- we may have changed our minds about how these analyses should be
# done since, and we want to suggest better ways
# -- the R language changes with each release of the base system, and
# certainly the functional data analysis functions change as well
# -- we might choose to offer new analyses from time to time by
# augmenting those in the book
# -- many illustrations in the book were produced using Matlab, which
# inevitably can imply slightly different results and graphical
# displays
# -- we may have changed our minds about variable names. For example,
# we now prefer "yearRng" to "yearRng" for the weather data.
# -- three of us wrote the book, and the person preparing these scripts
# might not be the person who wrote the text
# Moreover, we expect to augment and modify these command scripts from time
# to time as we get new data illustrating new things, add functionality
# to the package, or just for fun.
###
### ch. 6. Descriptions of Functional Data
###
library(fda)
# load the fda package
library(fda)
# display the data files associated with the fda package
data(package='fda')
# start the HTML help system if you are connected to the Internet, in
# order to open the R-Project documentation index page in order to obtain
# information about R or the fda package.
help.start()
##
## Section 6.1 Some Functional Descriptive Statistics
##
# ---------- Statistics for the log precipitation data ---------------
# using 'logprec.fd' computed in fdarm-ch05.R as follows:
# organize data to have winter in the center of the plot
logprecav = CanadianWeather$dailyAv[
dayOfYearShifted, , 'log10precip']
# set up a saturated basis: as many basis functions as observations
yearRng = c(0,365)
daybasis = create.fourier.basis(yearRng, 365)
# define the harmonic acceleration operator
Lcoef = c(0,(2*pi/diff(yearRng))^2,0)
harmaccelLfd = vec2Lfd(Lcoef, yearRng)
# smooth data with lambda that minimizes GCV
lambda = 1e6
fdParobj = fdPar(daybasis, harmaccelLfd, lambda)
logprec.fd = smooth.basis(day.5, logprecav, fdParobj)$fd
# elementary pointwise mean and standard deviation
meanlogprec = mean(logprec.fd)
stddevlogprec = std.fd(logprec.fd)
# Section 6.1.1 The Bivariate Covariance Function v(s; t)
logprecvar.bifd = var.fd(logprec.fd)
weektime = seq(0,365,length=53)
logprecvar_mat = eval.bifd(weektime, weektime,
logprecvar.bifd)
# Figure 6.1
persp(weektime, weektime, logprecvar_mat,
theta=-45, phi=25, r=3, expand = 0.5,
ticktype='detailed',
xlab="Day (July 1 to June 30)",
ylab="Day (July 1 to June 30)",
zlab="variance(log10 precip)")
contour(weektime, weektime, logprecvar_mat,
xlab="Day (July 1 to June 30)",
ylab="Day (July 1 to June 30)")
# Figure 6.2
day5time = seq(0,365,5)
logprec.varmat = eval.bifd(day5time, day5time,
logprecvar.bifd)
contour(day5time, day5time, logprec.varmat,
xlab="Day (July 1 to June 30)",
ylab="Day (July 1 to June 30)", lwd=2,
labcex=1)
##
## Section 6.2 The Residual Variance-Covariance Matrix Se
##
# (no computations in this section)
##
## Section 6.3 Functional Probes rho[xi]
##
# see section 6.5 below
##
## Section 6.4 Phase-plane Plots of Periodic Effects
##
# ----------- Phase-plane plots for the nondurable goods data ---------
# set up a basis for smoothing log nondurable goods index
goodsbasis = create.bspline.basis(rangeval=c(1919,2000),
nbasis=979, norder=8)
# smooth the data using function smooth.basisPar, which
# does not require setting up a functional parameter object
LfdobjNonDur= int2Lfd(4)
logNondurSm = smooth.basisPar(argvals=time(nondurables),
y=log10(coredata(nondurables)), fdobj=goodsbasis,
Lfdobj=LfdobjNonDur, lambda=1e-11)
# Fig. 6.3 The log nondurable goods index for 1964 to 1967
sel64.67 = ((1964<=time(nondurables)) &
(time(nondurables)<=1967) )
plot(time(nondurables)[sel64.67],
log10(nondurables[sel64.67]), xlab='Year',
ylab='Log10 Nondurable Goods Index', las=1)
abline(v=1965:1966, lty='dashed')
t64.67 = seq(1964, 1967, len=601)
lines(t64.67, predict(logNondurSm, t64.67))
# Section 6.4.1. Phase-plane Plots Show Energy Transfer
# Figure 6.4. Phase-plane plot for a simple harmonic function
sin. = expression(sin(2*pi*x))
D.sin = D(sin., "x")
D2.sin = D(D.sin, "x")
with(data.frame(x=seq(0, 1, length=46)),
plot(eval(D.sin), eval(D2.sin), type="l",
xlim=c(-10, 10), ylim=c(-50, 50),
xlab="Velocity", ylab="Acceleration"), las=1 )
pi.2 = (2*pi)
#lines(x=c(-pi.2,pi.2), y=c(0,0), lty=3)
pi.2.2= pi.2^2
lines(x=c(0,0), y=c(-pi.2.2, pi.2.2), lty="dashed")
lines(x=c(-pi.2, pi.2), y=c(0,0), lty="dashed")
text(c(0,0), c(-47, 47), rep("Max. potential energy", 2))
text(c(-8.5,8.5), c(0,0), rep("Max\nkinetic\nenergy", 2))
# Section 6.4.2 The Nondurable Goods Cycles
# Figure 6.5
phaseplanePlot(1964, logNondurSm$fd)
# sec. 6.4.3. Phase-Plane Plotting the Growth of Girls
# ------------- Phase-plane diagrams for the growth data ---------------
gr.basis = create.bspline.basis(norder=6, breaks=growth$age)
children = 1:10
ncasef = length(children)
cvecf = matrix(0, gr.basis$nbasis, ncasef)
dimnames(cvecf) = list(gr.basis$names,
dimnames(growth$hgtf)[[2]][children])
gr.fd0 = fd(cvecf, gr.basis)
gr.fdPar1.5 = fdPar(gr.fd0, Lfdobj=3, lambda=10^(-1.5))
hgtfmonfd = with(growth, smooth.monotone(age, hgtf[,children],
gr.fdPar1.5) )
agefine = seq(1,18,len=101)
(i11.7 = which(abs(agefine-11.7) == min(abs(agefine-11.7)))[1])
velffine = predict(hgtfmonfd, agefine, 1);
accffine = predict(hgtfmonfd, agefine, 2);
plot(velffine, accffine, type='n', xlim=c(0, 12), ylim=c(-5, 2),
xlab='Velocity (cm/yr)', ylab=expression(Acceleration (cm/yr^2)),
las=1)
for(i in 1:10){
lines(velffine[, i], accffine[, i])
points(velffine[i11.7, i], accffine[i11.7, i])
}
abline(h=0, lty='dotted')
##
## Section 6.5 Confidence Intervals for Curves and their Derivatives
##
# sec. 6.5.1. Two Linear mappings Defining a Probe Value
# ----------------- Probe values for Canadian weather data ------------
# define a probe to emphasize mid-winter
dayvec = seq(0,365,len=101)
xivec = exp(20*cos(2*pi*(dayvec-197)/365))
xibasis = create.bspline.basis(c(0,365),13)
xifd = smooth.basis(dayvec, xivec, xibasis)$fd
plot(xifd)
# define bases for temperature and precipitation
tempbasis = create.fourier.basis(c(0,365),65)
precbasis = create.fourier.basis(c(0,365),365)
# probe values for basis functions with respect to xifd
tempLmat = inprod(tempbasis, xifd)
precLmat = inprod(precbasis, xifd)
# sec. 6.5.3. Confidence Limits for Prince Rupert's Log Precipitation
logprecav = CanadianWeather$dailyAv[
dayOfYearShifted, , 'log10precip']
# as in section 5.3
# smooth data with lambda that minimizes GCV getting
# all of the output up to matrix y2cMap
yearRng = c(0,365)
daybasis = create.fourier.basis(yearRng, 365)
Lcoef = c(0,(2*pi/diff(yearRng))^2,0)
harmaccelLfd = vec2Lfd(Lcoef, yearRng)
lambda = 1e6
fdParobj = fdPar(daybasis, harmaccelLfd, lambda)
logprecList = smooth.basis(day.5, logprecav, fdParobj)
logprec.fd = logprecList$fd
fdnames = list("Day (July 1 to June 30)",
"Weather Station" = CanadianWeather$place,
"Log10 Precipitation (mm)")
logprec.fd$fdnames = fdnames
# compute the residual matrix and variance vector
logprecmat = eval.fd(day.5, logprec.fd)
logprecres = logprecav - logprecmat
logprecvar = apply(logprecres^2, 1, sum)/(35-1)
# smooth log variance vector
lambda = 1e8
resfdParobj = fdPar(daybasis, harmaccelLfd, lambda)
logvar.fd = smooth.basis(day.5, log(logprecvar), resfdParobj)$fd
# evaluate the exponentiated log variance vector and
# set up diagonal error variance matrix SigmaE
varvec = exp(eval.fd(day.5, logvar.fd))
SigmaE = diag(as.vector(varvec))
# compute variance covariance matrix for fit
y2cMap = logprecList$y2cMap
c2rMap = eval.basis(day.5, daybasis)
Sigmayhat = c2rMap %*% y2cMap %*% SigmaE %*%
t(y2cMap) %*% t(c2rMap)
# extract standard error function for yhat
logprec.stderr= sqrt(diag(Sigmayhat))
# plot Figure 6.6
logprec29 = eval.fd(day.5, logprec.fd[29])
plot(logprec.fd[29], lwd=2, ylim=c(0.2, 1.3))
lines(day.5, logprec29 + 2*logprec.stderr,
lty=2, lwd=2)
lines(day.5, logprec29 - 2*logprec.stderr,
lty=2, lwd=2)
points(day.5, logprecav[,29])
##
## Section 6.6 Some Things to Try
##
# (exercises for the reader)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.