@@ -2,138 +2,168 @@ Data2fd <- function(argvals=NULL, y=NULL, basisobj=NULL, nderiv=NULL,
2
2
lambda = 3e-8 / diff(as.numeric(range(argvals ))),
3
3
fdnames = NULL , covariates = NULL , method = " chol" ) {
4
4
5
- # Last modified 1 March 2024
5
+ # Last modified 15 March 2024 by Jim
6
6
7
- # . Tests five situations requiring modification or termination.
7
+ # . Data2fd is a simplified version of other smoothing functions that allows
8
+ # . neophytes or those in a hurry to smooth data successfully even though
9
+ # . one or more of its arguments is deficient in commonly occurring ways.
10
+
11
+ # . First invoke function argvalSwap() to see if any arguments are
12
+ # . illegitimate, and repair them if possible.
13
+
14
+ # . Five situations requiring modification or termination:
15
+ # . 1. if argvals and y should be swapped
16
+ # 2. if argvals is now NULL, build argvals and basisobj
17
+ # 3. if the dimensions argvals and y as.array match, build basisobj
18
+ # . 4. if length(dimy) < length(dima) swap argvals and y and their
19
+ # dimensions dimy and dima
20
+ # . 5. if basisobj has the wrong class, search other classes for the
21
+ # basis object, and change. Otherwise terminate.
8
22
9
23
argChk <- argvalsySwap(argvals , y , basisobj )
10
24
25
+ # check that argvals are numeric
26
+
11
27
if (! is.numeric(AV <- argChk $ argvals )){
12
- if (is.null(AV ))
13
- stop(' is.null(argChk$argvals); should be numeric' )
28
+ # terminal message
29
+ if (is.null(AV )) stop(' is.null(argChk$argvals); should be numeric' )
30
+ # . otherwise alert message
14
31
cat(' argChk$argvals is not numeric.\n ' )
15
32
cat(' class(argChk$argvals) = ' , class(AV ), ' \n ' )
16
- }
33
+ print(AV )
34
+ }
17
35
18
- # . Success and smoothing ... S3 object of class fdSmooth is returned
36
+ # . S3 object of class fdSmooth is returned by function smooth.basisPar()
19
37
20
- smBasis <- smooth.basisPar(argChk $ argvals , argChk $ y ,
38
+ fdSmoothobj <- smooth.basisPar(argChk $ argvals , argChk $ y ,
21
39
fdobj = basisobj , Lfdobj = nderiv , lambda = lambda ,
22
40
fdnames = fdnames ,
23
41
covariates = covariates , method = " chol" )
24
- return (smBasis $ fd )
42
+
43
+ # return only the fd component
44
+
45
+ return (fdSmoothobj $ fd )
25
46
26
47
}
27
48
28
49
# -------------------------------------------------------------------------
29
50
30
- # # 2020-01-16: Spencer Graves makes argvalsySwap
31
- # # An internal function that tests for 6 situations that require modification
32
- # # with a warning, or a terminal error message
33
-
34
51
argvalsySwap = function (argvals = NULL , y = NULL , basisobj = NULL ) {
35
52
53
+ # Last modified 15 March 2024 by Jim
54
+
36
55
if (inherits(basisobj , ' basisfd' )) rangeval <- basisobj $ rangeval
37
56
38
57
# #. --------------------------------------------------------------------------
39
- # # Section 1. if(is.null(y)) use argvals for y
58
+ # # 1. If argument argvals is NULL, swap it with y
40
59
# #. --------------------------------------------------------------------------
41
60
42
61
if (is.null(y )){
43
62
if (is.null(argvals )) stop(" 'y' is missing with no default" )
44
63
# Store argvals as y and alert
45
64
cat(" 'y' is missing, using 'argvals'\n " )
46
- y <- argvals
65
+ y <- argvals
47
66
argvals <- NULL
48
67
}
49
68
50
69
# #. --------------------------------------------------------------------------
51
- # # Section 2. test for missing argvals, if so construct a sequence
70
+ # # 2. If argument argvals is now NULL, then:
71
+ # # if basisobj is null, use default basis object
72
+ # # else if basisobj is numeric, default basis object
73
+ # # if length of basis object is > 1 default basis object
74
+ # # else default basis object with order = numeric value
75
+ # # else if basisobj is "fd" basisobj = fd$basis
76
+ # # else if basisobj is "fdPar" basisobj = fdPar$fd$basis
77
+ # # else stop with message
78
+ # # set rangevalue to basisobj$rangeval but stop if is NULL
79
+ # # return with warning all three arguments
52
80
# #. --------------------------------------------------------------------------
53
81
54
82
dimy <- dim(as.array(y ))
55
- if (is.null(argvals )) {
56
- # the following code block is run if TRUE
57
- { # beginning of code block
83
+ if (is.null(argvals )) {
84
+ {
58
85
if (is.null(basisobj )){
59
86
basisobj <- create.bspline.basis(basisobj )
60
87
} else {
61
88
if (is.numeric(basisobj )) {
62
- if (length(basisobj )> 1 ) {
89
+ if (length(basisobj ) > 1 ) {
63
90
basisobj <- create.bspline.basis(basisobj )
64
- } else
91
+ } else
65
92
basisobj <- create.bspline.basis(norder = basisobj )
66
93
}
67
94
else {
68
- if (inherits(basisobj , ' fd' )){
95
+ if (inherits(basisobj , ' fd' )) {
69
96
basisobj <- basisobj $ basis
70
- } else
97
+ } else
71
98
if (inherits(basisobj , ' fdPar' ))
72
99
basisobj <- basisobj $ fd $ basis
73
100
}
74
101
}
75
- } # . end of code block
76
- # This is executed whether or not the previous was
77
- # . locate the range from basisobj
78
- a01 <- basisobj $ rangeval
79
- # if range is null, error message and stop
80
- if (is.null(a01 ))
102
+ }
103
+ rangeval <- basisobj $ rangeval
104
+ if (is.null(rangeval ))
81
105
stop(' basisobj does not have a required rangeval component.' )
106
+ #
82
107
n <- dimy [1 ]
83
- cat(paste(" 'argvals' is missing; using seq(" , a01 [1 ],
84
- " , " , a01 [2 ], " , length=" , n , " )\n " ))
85
- # construct the argval sequence
86
- argvals <- seq(a01 [1 ], a01 [2 ], length = n )
87
-
108
+ # . alert message
109
+ cat(paste(" 'argvals' is missing; using seq(" , rangeval [1 ],
110
+ " , " , rangeval [2 ], " , length=" , n , " )\n " ))
111
+ argvals <- seq(rangeval [1 ], rangeval [2 ], length = n )
88
112
return (list (argvals = argvals , y = y , basisobj = basisobj ))
89
-
90
113
}
91
114
92
115
# #. --------------------------------------------------------------------------
93
- # # 3. swapping y and argvals
116
+ # # 3. dimy and dima are dimensions of argvals and y as array objects
117
+ # # If they match, proceed as in step 2 to construct basisobj
118
+ # # else stop with message
94
119
# #. --------------------------------------------------------------------------
95
120
96
- dima <- dim(as.array(argvals ))
97
- { # First line in code block
98
- if (length(dimy ) == length(dima )) {
121
+ dima <- dim(as.array(argvals ))
122
+ {
123
+ if (length(dimy ) == length(dima )){
99
124
if (any(dimy != dima ))
125
+ # . terminal message
100
126
stop(" dimensions of 'argvals' and 'y' must be compatible;\n " ,
101
127
" dim(argvals) = " , paste(dima , collapse = ' x ' ),
102
128
" ; dim(y) = " , paste(dimy , collapse = ' x ' ) )
103
129
# Check basisobj
104
- { # First line in code block
130
+ {
105
131
if (inherits(basisobj , ' fd' )) basisobj <- basisobj $ basis
106
132
else {
107
133
if (inherits(basisobj , ' fdPar' ))
108
134
basisobj <- basisobj $ fd $ basis
109
135
else {
110
- if (inherits(basisobj , ' array' )) {
111
- fd. <- fd(basisobj )
136
+ if (inherits(basisobj , ' array' )){
137
+ fd. <- fd(basisobj )
112
138
basisobj <- fd. $ basis
113
- } else {
139
+ }
140
+ else {
114
141
if (inherits(basisobj , ' integer' ))
115
142
basisobj <- create.bspline.basis(argvals , norder = basisobj )
116
143
else {
117
- if (is.null(basisobj ))
144
+ if (is.null(basisobj )) {
118
145
basisobj <- create.bspline.basis(argvals )
146
+ }
119
147
else
120
148
if (! inherits(basisobj , ' basisfd' ))
149
+ # . terminal message
121
150
stop(" 'basisobj' is NOT a functional basis" ,
122
151
" object (class 'basisfd'); class = " ,
123
152
class(basisobj )[1 ])
124
153
}
125
154
}
126
155
}
127
156
}
128
- } # Last line in code block
129
- a01 <- basisobj $ rangeval
130
- arng <- range( argvals )
157
+ }
158
+ arng <- range( argvals )
159
+ rangeval <- basisobj $ rangeval
131
160
if ((rangeval [1 ]< = arng [1 ]) && (arng [2 ]< = rangeval [2 ])) {
132
161
return (list (argvals = argvals , y = y , basisobj = basisobj ))
133
162
}
134
163
#
135
164
yrng <- range(y )
136
- if ((a01 [1 ]< = yrng [1 ]) && (yrng [2 ]< = a01 [2 ])) {
165
+ if ((rangeval [1 ]< = yrng [1 ]) && (yrng [2 ]< = rangeval [2 ])) {
166
+ # . alert message
137
167
cat(paste(" 'argvals' is NOT contained in basisobj$rangeval" ,
138
168
" , but 'y' is; swapping 'argvals' and 'y'.\n " ))
139
169
return (list (argvals = y , y = argvals , basisobj = basisobj ))
@@ -142,10 +172,12 @@ argvalsySwap = function(argvals=NULL, y=NULL, basisobj=NULL) {
142
172
stop(" Neither 'argvals' nor 'y' are contained in " ,
143
173
" basisobj$rangeval" )
144
174
}
145
- } # Last line in code block
175
+ }
146
176
147
177
# #. --------------------------------------------------------------------------
148
- # # 4. If(length(dimy) < length(dima)) swap argvals and y
178
+ # # 4. If length(dimy) < length(dima) swap argvals and y and their
179
+ # # dimensions dimy and dima
180
+ # # Then stop if a value in dima is not in dimy
149
181
# #. --------------------------------------------------------------------------
150
182
151
183
if (length(dimy )< length(dima )) {
@@ -161,18 +193,20 @@ argvalsySwap = function(argvals=NULL, y=NULL, basisobj=NULL) {
161
193
dima <- dimy
162
194
dimy <- d.
163
195
}
164
-
196
+ # error message if argvals and y are inconsistent
165
197
if (any(dima != dimy [1 : length(dima )]))
198
+ # terminal message
166
199
stop(" A dimension of 'argvals' does not match 'y':\n " ,
167
200
" dim(argvals) = " , paste(dima , collapse = " x " ),
168
201
" ; dim(y) = " , paste(dimy , collapse = " x " ) )
169
202
170
203
# #. --------------------------------------------------------------------------
171
- # # 5. Check compatibility of argvals with basisobj
204
+ # # 5. check basisobj for having the wrong class, and is so
205
+ # proceed as above to find an object with the right class
172
206
# #. --------------------------------------------------------------------------
173
207
174
- { # First line in code block
175
- if (inherits(basisobj , ' fd' ))basisobj <- basisobj $ basis
208
+ {
209
+ if (inherits(basisobj , ' fd' )) basisobj <- basisobj $ basis
176
210
else {
177
211
if (inherits(basisobj , ' fdPar' ))
178
212
basisobj <- basisobj $ fd $ basis
@@ -189,20 +223,28 @@ argvalsySwap = function(argvals=NULL, y=NULL, basisobj=NULL) {
189
223
basisobj <- create.bspline.basis(argvals )
190
224
else
191
225
if (! inherits(basisobj , ' basisfd' ))
226
+ # . error message if basisobj incorrect class
192
227
stop(" 'basisobj' is NOT a functional basis" ,
193
228
" object (class 'basisfd'); class = " ,
194
229
class(basisobj )[1 ])
195
230
}
196
231
}
197
232
}
198
233
}
199
- } # Last line in code block
200
- a01 <- basisobj $ rangeval
234
+ rangeval <- basisobj $ rangeval
235
+ }
236
+
237
+ # #. --------------------------------------------------------------------------
238
+ # # 6. Check compatibility of argvals with basisobj$rangeval
239
+ # #. --------------------------------------------------------------------------
240
+
241
+ a01 <- basisobj $ rangeval
201
242
arng <- range(argvals )
202
- if ((a01 [1 ]< = arng [1 ]) && (arng [2 ] < = a01 [2 ])) {
243
+ if ((a01 [1 ] < = arng [1 ]) && (arng [1 ] < = a01 [2 ])) {
203
244
return (list (argvals = argvals , y = y , basisobj = basisobj ))
204
245
}
205
- #
206
- stop(" 'argvals' are not contained in basisobj$rangeval" )
246
+ # error message
247
+ stop(" There are argvals not contained within basisobj$rangeval" )
248
+
207
249
}
208
250
0 commit comments