This function converts an array y
of function values plus an
array argvals
of argument values into a functional data object.
This function tries to do as much for the user as possible in setting
up a call to function smooth.basis
. Be warned that the result
may not be a satisfactory smooth of the data, and consequently that it
may be necessary to use function smooth.basis
instead, the help
file for which provides a great deal more information than is provided
here.
Also, function Data2fd
can swap the first two arguments,
argvals
and y
if it appears that they have been included
in reverse order. A warning message is returned if this swap takes place.
Any such automatic decision, though, has the possibility of being wrong,
and the results should be carefully checked. Preferably, the order of
the arguments should be respected: argvals
comes first and
y
comes second.
1 2 3 4 
argvals 
a set of argument values. If this is a vector, the same set of
argument values is used for all columns of Dimensions for 
y 
an array containing sampled values of curves. If 
basisobj 
One of the following:

nderiv 
Smoothing typically specified as an integer order for the derivative
whose square is integrated and weighted by A general linear differential operator can also be supplied. 
lambda 
weight on the smoothing operator specified by 
fdnames 
Either a charater vector of length 3 or a named list of length 3. In either case, the three elements correspond to the following:
If fdnames is a list, the components provide labels for the levels
of the corresponding dimension of 
covariates 
the observed values in 
method 
by default the function uses the usual textbook equations for computing
the coefficients of the basis function expansions. But, as in regression
analysis, a price is paid in terms of rounding error for such
computations since they involved crossproducts of basis function
values. Optionally, if 
dfscale 
the generalized crossvalidation or "gcv" criterion that is often used
to determine the size of the smoothing parameter involves the
subtraction of an measue of degrees of freedom from 
This function tends to be used in rather simple applications where
there is no need to control the roughness of the resulting curve with
any great finesse. The roughness is essentially controlled by how
many basis functions are used. In more sophisticated applications, it
would be better to use the function smooth.basisPar
.
an object of the fd
class containing:
coefs 
the coefficient array 
basis 
a basis object 
fdnames 
a list containing names for the arguments, function values and variables 
Ramsay, James O., and Silverman, Bernard W. (2006), Functional Data Analysis, 2nd ed., Springer, New York.
Ramsay, James O., and Silverman, Bernard W. (2002), Applied Functional Data Analysis, Springer, New York.
smooth.basisPar
,
smooth.basis
,
project.basis
,
smooth.fd
,
smooth.monotone
,
smooth.pos
day.5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136  ##
## Simplest possible example: constant function
##
# 1 basis, order 1 = degree 0 = constant function
b1.1 < create.bspline.basis(nbasis=1, norder=1)
# data values: 1 and 2, with a mean of 1.5
y12 < 1:2
# smooth data, giving a constant function with value 1.5
fd1.1 < Data2fd(y12, basisobj=b1.1)
plot(fd1.1)
# now repeat the analysis with some smoothing, which moves the
# toward 0.
fd1.1.5 < Data2fd(y12, basisobj=b1.1, lambda=0.5)
# values of the smooth:
# fd1.1.5 = sum(y12)/(n+lambda*integral(over arg=0 to 1 of 1))
# = 3 / (2+0.5) = 1.2
eval.fd(seq(0, 1, .2), fd1.1.5)
##
## step function smoothing
##
sessionInfo()
find("crossprod")
# 2 step basis functions: order 1 = degree 0 = step functions
b1.2 < create.bspline.basis(nbasis=2, norder=1)
# fit the data without smoothing
fd1.2 < Data2fd(1:2, basisobj=b1.2)
# plot the result: A step function: 1 to 0.5, then 2
op < par(mfrow=c(2,1))
plot(b1.2, main='bases')
plot(fd1.2, main='fit')
par(op)
##
## Simple oversmoothing
##
# 3 step basis functions: order 1 = degree 0 = step functions
b1.3 < create.bspline.basis(nbasis=3, norder=1)
# smooth the data with smoothing
fd1.3.5 < Data2fd(y12, basisobj=b1.3, lambda=0.5)
# plot the fit along with the points
plot(0:1, c(0, 2), type='n')
points(0:1, y12)
lines(fd1.3.5)
# Fit = penalized least squares with penalty =
# = lambda * integral(0:1 of basis^2),
# which shrinks the points towards 0.
# X1.3 = matrix(c(1,0, 0,0, 0,1), 2)
# XtX = crossprod(X1.3) = diag(c(1, 0, 1))
# penmat = diag(3)/3
# = 3x3 matrix of integral(over arg=0:1 of basis[i]*basis[j])
# Xt.y = crossprod(X1.3, y12) = c(1, 0, 2)
# XtX + lambda*penmat = diag(c(7, 1, 7)/6
# so coef(fd1.3.5) = solve(XtX + lambda*penmat, Xt.y)
# = c(6/7, 0, 12/7)
##
## linear spline fit
##
# 3 bases, order 2 = degree 1
b2.3 < create.bspline.basis(norder=2, breaks=c(0, .5, 1))
# interpolate the values 0, 2, 1
fd2.3 < Data2fd(c(0,2,1), basisobj=b2.3, lambda=0)
# display the coefficients
round(fd2.3$coefs, 4)
# plot the results
op < par(mfrow=c(2,1))
plot(b2.3, main='bases')
plot(fd2.3, main='fit')
par(op)
# apply some smoothing
fd2.3. < Data2fd(c(0,2,1), basisobj=b2.3, lambda=1)
op < par(mfrow=c(2,1))
plot(b2.3, main='bases')
plot(fd2.3., main='fit', ylim=c(0,2))
par(op)
##
## quadratic spline fit
##
# 4 bases, order 3 = degree 2 = continuous, bounded, locally quadratic
b3.4 < create.bspline.basis(norder=3, breaks=c(0, .5, 1))
# fit values c(0,4,2,3) without interpolation
fd3.4 < Data2fd(c(0,4,2,3), basisobj=b3.4, lambda=0)
round(fd3.4$coefs, 4)
op < par(mfrow=c(2,1))
plot(b3.4)
plot(fd3.4)
points(c(0,1/3,2/3,1), c(0,4,2,3))
par(op)
# try smoothing
fd3.4. < Data2fd(c(0,4,2,3), basisobj=b3.4, lambda=1)
round(fd3.4.$coef, 4)
op < par(mfrow=c(2,1))
plot(b3.4)
plot(fd3.4., ylim=c(0,4))
points(seq(0,1,len=4), c(0,4,2,3))
par(op)
##
## Two simple Fourier examples
##
gaitbasis3 < create.fourier.basis(nbasis=5)
gaitfd3 < Data2fd(gait, basisobj=gaitbasis3)
plotfit.fd(gait, seq(0,1,len=20), gaitfd3)
# set up the fourier basis
daybasis < create.fourier.basis(c(0, 365), nbasis=65)
# Make temperature fd object
# Temperature data are in 12 by 365 matrix tempav
# See analyses of weather data.
tempfd < Data2fd(CanadianWeather$dailyAv[,,"Temperature.C"],
day.5, daybasis)
# plot the temperature curves
par(mfrow=c(1,1))
plot(tempfd)
##
## argvals of class Date and POSIXct
##
# Date
invasion1 < as.Date('17750904')
invasion2 < as.Date('18120712')
earlyUS.Canada < c(invasion1, invasion2)
BspInvasion < create.bspline.basis(earlyUS.Canada)
earlyYears < seq(invasion1, invasion2, length.out=7)
(earlyQuad < (as.numeric(earlyYearsinvasion1)/365.24)^2)
fitQuad < Data2fd(earlyYears, earlyQuad, BspInvasion)
# POSIXct
AmRev.ct < as.POSIXct1970(c('17760704', '17890430'))
BspRev.ct < create.bspline.basis(AmRev.ct)
AmRevYrs.ct < seq(AmRev.ct[1], AmRev.ct[2], length.out=14)
(AmRevLin.ct < as.numeric(AmRevYrs.ctAmRev.ct[1]))
fitLin.ct < Data2fd(AmRevYrs.ct, AmRevLin.ct, BspRev.ct)

Questions? Problems? Suggestions? Tweet to @rdrrHQ or email at ian@mutexlabs.com.
All documentation is copyright its authors; we didn't write any of that.