-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathPS.R
executable file
·152 lines (152 loc) · 5.87 KB
/
PS.R
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#----------------------------------------------------------------------------------------
ps<-function(x, df = 3, lambda = NULL, ps.intervals = 20, degree = 3, order = 3)
{
# this function is based on B. Marx penalised splines function
# (c) 1995 Brian D. Marx
# require(splines)
scall <- deparse(sys.call())
if(is.null(lambda)&is.null(df)) stop("df or lambda should be set \n")
number.knots <- ps.intervals + 2 * degree + 1
x.domain <- as.vector(x)
xl <- min(x.domain)
xr <- max(x.domain)
xmax <- xr + 0.01 * (xr - xl)
xmin <- xl - 0.01 * (xr - xl)
dx <- (xmax - xmin)/ps.intervals
nx <- names(x.domain)
nax <- is.na(x.domain)
if(nas <- any(nax))
x.domain <- x[!nax]
sorder <- degree + 1
Aknots <- range(x.domain)
nAknots <- ps.intervals - 1
if(nAknots < 1)
{
nAknots <- 1
warning(paste("ps.intervals was too small; have used 2"
))
}
if(nAknots > 0)
{
Aknots <- seq(from = xmin - degree * dx, to = xmax +
degree * dx, by = dx)
}
else knots <- NULL
basis <- splineDesign(Aknots, x.domain, sorder, 0 * x.domain)#$design
n.col <- ncol(basis)
dimnames(basis)<- list(1:nrow(basis), 1:n.col)
if((order - n.col + 1) > 0)
{
order <- n.col - 1
warning(paste("order was too large; have used ", n.col - 1))
}
if(df < 1) warning("the df are set to 1")
df <- if (df < 1) 1 else df+2
if (!is.null(lambda))
{
if(lambda < 0)
{ lambda <- 0
warning(paste("lambda was negative; have used ", lambda))
}
}
aug <- diag(n.col)
if(order != 0)
{
for(tt in 1:order)
{
aug <- diff(aug)
}
}
pen.aug <- aug
xvar <- x #rep(0,length(x))
attr(xvar, "knots") <- Aknots
attr(xvar, "pen.augment") <- pen.aug
attr(xvar, "design.matrix") <- basis
attr(xvar, "call") <- substitute(gamlss.ps(data[[scall]], z, w))
attr(xvar, "lambda") <- lambda
attr(xvar, "df") <- df
attr(xvar, "order") <- order
xvar
}
#----------------------------------------------------------------------------------------
gamlss.ps <- function(x, y, w, xeval = NULL, ...)
{
#-----------------------------------------------------------------
get.df <- function(lambda)
{
aug <- sqrt(lambda)*aug
xaug <- as.matrix(rbind(dm,aug))
df <- sum(diag(solve(t(xaug) %*% (waug * xaug))
%*% (t(dm) %*% (waug[1:N] * dm))))
df
}
#-----------------------------------------------------------------
find.lambda.from.df <- function(df)
{
usemode <- function(spar,df)
{
ndf <- get.df(spar)
fun <- (ndf-df)**2
}
a <- 0.000001 ; c <- 100000; t <- 0.0001 ; r <- 0.61803399;
z <- 1-r ; b <- r*a + z*c ; l4 <- a ; l3 <- c ; w1 <- 1 ;
l1 <- if(c-b > b-a) b else b-z*(b-a)
l2 <- if(c-b > b-a) b+z*(c-b) else b
f1 <- usemode(l1,df)
f2 <- usemode(l2,df)
while(w1>0)
{ if(f2 < f1) { l4<-l1; l1<-l2 ; l2<- r*l1+z*l3; z8<-f1 ; f1<-f2 ;
f2 <- usemode(l2,df)
}
else { l3<-l2 ; l2<-l1; l1<- r*l2+z*l4; z8<-f2 ; f2<-f1 ;
f1 <- usemode(l1,df)
}
w1 <- abs(l3-l4) > t*(abs(l1)+abs(l2))
}
lambda <- if(f1<f2) l1 else l2
lambda
}
#---------------------------------------------------------------
dm <- if (is.null(xeval)) as.matrix(attr(x,"design.matrix"))#ms Wednesday, July 21, for prediction
else as.matrix(attr(x,"design.matrix"))[seq(1,length(y)),]
# dm <- as.matrix(attr(x,"design.matrix"))
aug <- as.matrix(attr(x,"pen.augment"))
N <- dim(dm)[1]
p <- dim(dm)[2]
aN <- dim(aug)[1]
ap <- dim(aug)[2]
lambda <- as.vector(attr(x,"lambda"))
df <- as.vector(attr(x,"df"))
estimate <- as.logical(attr(x,"estimate"))
if(p!=ap) stop("the dimensions of the augmented matrix and of the design matrix are incompatible")
zeros <- rep(0,aN)
ones <- rep(1,aN)
yaug <- as.vector(c(y,zeros))
waug <- as.vector(c(w,ones))
if(!is.null(df)&is.null(lambda)){ lambda <- find.lambda.from.df(df)} # if df is set
aug <- sqrt(lambda)*aug
xaug <- as.matrix(rbind(dm,aug))
fit <- lm.wfit(xaug,yaug,w=waug,method="qr")
cov <- diag(chol2inv(fit$qr$qr[1:p, 1:p, drop = FALSE]))
nl.df <- sum(diag(solve(t(xaug) %*% (waug * xaug)) %*% (t(dm)
%*% (waug[1:N] * dm))))-2
resid.v <- resid(fit)[1:N]
lev <- hat(sqrt(waug)*xaug,intercept=FALSE)[1:N]
lev <- (lev-.hat.WX(w,x))
var <- lev/w #
fitted.v <- fitted(fit)[1:N]
coefSmo <- list(coef=coef(fit), varcoeff=cov)
if (is.null(xeval))
{
list(fitted.values=fitted.v, residuals=resid.v, var=var, nl.df =nl.df,
lambda=lambda, coefSmo=coefSmo )
}
else
{
#ndm <- as.matrix(attr(x,"design.matrix"))[seq(length(y)+1, 2),]
ll <- dim(as.matrix(attr(x,"design.matrix")))[1]
nxvar <- as.matrix(attr(x,"design.matrix"))[seq(length(y)+1,ll),]
pred <- drop(nxvar %*% coef(fit))
pred
}
}