Hi,

If you didn't receive the attachment properly, here it is again.

Ravi.

----------------------------------------------------------------------------
-------

Ravi Varadhan, Ph.D.

Assistant Professor, The Center on Aging and Health

Division of Geriatric Medicine and Gerontology 

Johns Hopkins University

Ph: (410) 502-2619

Fax: (410) 614-9625

Email: [EMAIL PROTECTED]

Webpage:  http://www.jhsph.edu/agingandhealth/People/Faculty/Varadhan.html

 

----------------------------------------------------------------------------
--------


-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
Behalf Of Ravi Varadhan
Sent: Wednesday, March 05, 2008 4:58 PM
To: 'Spencer Graves'; 'Levi Waldron'
Cc: 'R-help mailing list'
Subject: Re: [R] differentiating a numeric vector

Hi,

Here is another approach, in addition to the suggestions made by Spencer and
Gabor.  It uses the spm() function in SemiPar package.  An advantage of this
approach is that the smoothing parameter is automatically estimated using
REML (here I use default knot locations, but this can be specified
explicitly).  

You also need to source in the plot.spm() function that I have created by
slightly modifying the plot.spm() that comes with SemiPar.  This is
necessary to obtain numerical values of derivatives at x-locations in
addition to simply plotting the derivative curves.

library(SemiPar)

source("plotspm.r")

# An example

k <- 10

x <- sqrt(runif(500))

y <- pnorm(x) + sin(k*pi*x^2) + rnorm(500,mean=0,sd=0.5)

fit<-spm(y ~ f(x, basis="trunc.poly", degree=3), omit.missing=TRUE)

deriv <- plot(fit, drv=1)  # plot and store first derivative

deriv2 <- plot(fit, drv=2) # plot and store second derivative 


Hope this helps,
Ravi.

----------------------------------------------------------------------------
-------

Ravi Varadhan, Ph.D.

Assistant Professor, The Center on Aging and Health

Division of Geriatric Medicine and Gerontology 

Johns Hopkins University

Ph: (410) 502-2619

Fax: (410) 614-9625

Email: [EMAIL PROTECTED]

Webpage:  http://www.jhsph.edu/agingandhealth/People/Faculty/Varadhan.html

 

----------------------------------------------------------------------------
--------


-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
Behalf Of Spencer Graves
Sent: Wednesday, March 05, 2008 4:11 PM
To: Levi Waldron
Cc: R-help mailing list
Subject: Re: [R] differentiating a numeric vector

      Have you looked at the 'fda' package?  It has many functions for 
doing what you want.  A strength is that it is a companion package for 
two books on that and related issues, and includes script files under 
"~R.installation.directory\library\fda\scripts" to reproduce some of the 
analyses.  It may include more than you want to consider, but for me, 
too much is usually better than nothing. 

      hope this helps. 
      Spencer Graves
p.s.  If you try it and have trouble, please submit another question 
including commented, minimal, self-contained, reproducible code, as 
requested in the posting guide 
http://www.R-project.org/posting-guide.html. 

Levi Waldron wrote:
> What functions exist for differentiating a numeric vector (in my case
> spectral data)?  That is, experimental data without an analytical
> function.  ie,
>
>   
>> x <- seq(1,10,0.1)
>> y=x^3+rnorm(length(x),sd=0.01)     #although the real function would be
nothing simple like x^3...
>> derivy <- ....
>>     
>
> I know I could just use diff(y) but it would be nice to estimate
> derivatives at the endpoints, calculate higher-order derivatives, and
> maybe have some smoothing options ie by differentiating a spline or
> something like that.
>
> ______________________________________________
> R-help@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>

______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
plot.spm <- function (x, ...) 
{
    object <- x
    plot.params <- plotControl(...)
    drv <- plot.params$drv
    se <- plot.params$se
    shade <- plot.params$shade
    default.ylim <- FALSE
    if (is.null(plot.params$ylim)) 
        default.ylim <- TRUE
    lin.present <- !is.null(object$info$lin)
    pen.present <- !is.null(object$info$pen)
    krige.present <- !is.null(object$info$krige)
    random.present <- !is.null(object$info$random)
    const.only <- ((!lin.present) & (!pen.present) & (!krige.present) & 
        (!random.present))
    block.inds <- object$aux$block.inds
    if (pen.present | krige.present) 
        coefs <- c(object$fit$coef$fixed, object$fit$coef$random)
    else coefs <- object$fit$coef$fixed
    if (se == TRUE) 
        cov.mat <- object$aux$cov.mat
    if (random.present) {
        random.inds <- block.inds[[length(block.inds)]]
        coefs <- coefs[-random.inds]
        if (se == TRUE) 
            cov.mat <- cov.mat[-random.inds, -random.inds]
    }
    basis <- object$info$pen$basis
    if (drv == 0) 
        ave.vals <- 1
    if (drv > 0) 
        ave.vals <- 0
    if (lin.present) 
        ave.vals <- c(ave.vals, apply(object$info$lin$x, 2, mean))
    if (pen.present) {
        num.pen <- ncol(as.matrix(object$info$pen$x))
        for (ipen in 1:num.pen) {
            deg.val <- object$info$pen$degree[ipen]
            if (basis == "trunc.poly") 
                ncol.X.val <- deg.val
            if (basis == "tps") 
                ncol.X.val <- (deg.val - 1)/2
            ave.val <- mean(as.matrix(object$info$pen$x)[, ipen])
            ave.vals <- c(ave.vals, ave.val)
            if (ncol.X.val > 1) 
                for (ipow in 2:ncol.X.val) ave.vals <- c(ave.vals, 
                  ave.val^ipow)
        }
    }
    if (!pen.present) 
        num.pen <- 0
    if (krige.present) {
        x1.v <- object$info$krige$x[, 1]
        x2.v <- object$info$krige$x[, 2]
        m.krige <- (object$info$krige$degree/2) + 1
        X.kg <- NULL
        for (im in 2:m.krige) {
            X.kg <- cbind(X.kg, x1.v^(im - 1))
            if (im > 2) 
                for (ipow in 2:(im - 1)) X.kg <- cbind(X.kg, 
                  (x1.v^(im - ipow)) * (x2.v^(ipow - 1)))
            X.kg <- cbind(X.kg, x2.v^(im - 1))
        }
        ave.vals <- c(ave.vals, apply(X.kg, 2, mean))
    }
    if (pen.present) {
        num.pen <- ncol(as.matrix(object$info$pen$x))
        for (ipen in 1:num.pen) {
            deg.val <- object$info$pen$degree[ipen]
            knots <- object$info$pen$knots[[ipen]]
            ave.val <- mean(as.matrix(object$info$pen$x)[, ipen])
            if (basis == "trunc.poly") {
                ave.val.knots <- ave.val - knots
                ave.val.knots <- (ave.val.knots * (ave.val.knots > 
                  0))^deg.val
            }
            if (basis == "tps") {
                ave.val.knots <- abs(ave.val - knots)^deg.val
                sqrt.Omega <- object$info$trans.mat[[ipen]]
                ave.val.knots <- t(solve(sqrt.Omega, ave.val.knots))
            }
            ave.vals <- c(ave.vals, ave.val.knots)
        }
    }
    if (krige.present) {
        ave.val.x1 <- mean(object$info$krige$x[, 1])
        ave.val.x2 <- mean(object$info$krige$x[, 2])
        knots <- object$info$krige$knots
        knots.1 <- knots[, 1]
        knots.2 <- knots[, 2]
        num.knots <- length(knots.1)
        ave.val.knots <- NULL
        dists.ave <- sqrt((ave.val.x1 - knots.1)^2 + (ave.val.x2 - 
            knots.2)^2)
        ave.val.knots <- tps.cov(dists.ave, m = m.krige, d = 2)
        ave.val.knots <- 
solve(object$info$trans.mat[[length(object$info$trans.mat)]], 
            as.matrix(ave.val.knots))
        ave.vals <- c(ave.vals, ave.val.knots)
    }
    if (const.only) {
        mean.est <- coefs[1]
        x.grid <- c(0.25, 0.75)
        se.val <- sqrt(diag(object$aux$cov.mat))[1]
        lower <- mean.est - 2 * se.val
        upper <- mean.est + 2 * se.val
        plot(0, 0, type = "n", xlim = c(0, 1), ylim = c(mean.est - 
            2.5 * se.val, mean.est + 2.5 * se.val), xaxt = "n", 
            xlab = "", ylab = "", bty = "l")
        if (se == TRUE) {
            if (shade == FALSE) {
                lines(x.grid, rep(lower, 2), lty = 2, lwd = 2, 
                  col = "black")
                lines(x.grid, rep(upper, 2), lty = 2, lwd = 2, 
                  col = "black")
            }
            if (shade == TRUE) 
                polygon(c(x.grid, rev(x.grid)), c(rep(lower, 
                  2), rep(upper, 2)), border = FALSE, col = "grey70")
        }
        lines(x.grid, rep(mean.est, 2), lwd = 2)
    }
    if (lin.present | pen.present) {
        curve.type <- NULL
        if (lin.present) 
            curve.type <- c(curve.type, rep("lin", 
ncol(as.matrix(object$info$lin$x))))
        if (pen.present) 
            curve.type <- c(curve.type, rep("pen", 
ncol(as.matrix(object$info$pen$x))))
        num.curves <- length(curve.type)
    }
    if (!(lin.present | pen.present)) 
        num.curves <- 0
    plot.params <- set.plot.dflts(object, plot.params, num.curves)
    if ((!is.null(plot.params$xlim)) & (!is.list(plot.params$xlim))) {
        if (length(plot.params$xlim) != 2) 
            stop("illegal xlim")
        plot.params$xlim <- list(lower = rep(plot.params$xlim[1], 
            num.curves), upper = rep(plot.params$xlim[2], num.curves))
    }
    if ((!is.null(plot.params$ylim)) & (!default.ylim) & 
(!is.list(plot.params$ylim))) {
        if (length(plot.params$ylim) != 2) 
            stop("illegal ylim")
        plot.params$ylim <- list(lower = rep(plot.params$ylim[1], 
            num.curves), upper = rep(plot.params$ylim[2], num.curves))
    }
    if (lin.present | pen.present) {
        x.vals <- NULL
        if (lin.present) 
            x.vals <- cbind(x.vals, object$info$lin$x)
        if (pen.present) 
            x.vals <- cbind(x.vals, object$info$pen$x)
        fc.stt.pos <- 2
        pen.num <- 1
        for (j in 1:num.curves) {
            grid.size <- plot.params$grid.size[j]
            if (drv == 0) 
                C.grid <- matrix(rep(ave.vals, grid.size), grid.size, 
                  length(ave.vals), byrow = TRUE)
            if (drv > 0) 
                C.grid <- matrix(0, grid.size, length(ave.vals))
            x.grid <- seq(plot.params$xlim$lower[j], plot.params$xlim$upper[j], 
                length = plot.params$grid.size[j])
            if (curve.type[j] == "lin") 
                deg.val <- 1
            if (curve.type[j] == "pen") 
                deg.val <- object$info$pen$degree[pen.num]
            X.g.inst <- NULL
            if (curve.type[j] == "lin") {
                if (drv == 0) 
                  X.g.inst <- cbind(X.g.inst, x.grid)
                if (drv == 1) 
                  X.g.inst <- cbind(X.g.inst, rep(1, grid.size[j]))
                if (drv > 1) 
                  X.g.inst <- cbind(X.g.inst, rep(0, grid.size[j]))
            }
            if (curve.type[j] == "pen") {
                if (basis == "trunc.poly") 
                  ncol.X.val <- deg.val
                if (basis == "tps") 
                  ncol.X.val <- (deg.val - 1)/2
                if (drv == 0) {
                  for (pow in 1:ncol.X.val) {
                    new.col.data <- x.vals[, j]^pow
                    new.col <- x.grid^pow
                    X.g.inst <- cbind(X.g.inst, new.col)
                  }
                }
                if (drv > 0) {
                  for (pow in 1:ncol.X.val) {
                    new.col.data <- x.vals[, j]^pow
                    pow.drv <- pow - drv
                    if (pow.drv >= 0) 
                      new.col <- prod(pow:(pow.drv + 1)) * (x.grid^pow.drv)
                    else new.col <- rep(0, length(x.grid))
                    X.g.inst <- cbind(X.g.inst, new.col)
                  }
                }
            }
            C.g.inst <- X.g.inst
            if (curve.type[j] == "lin") {
                inst.col.inds <- fc.stt.pos
                fc.stt.pos <- fc.stt.pos + 1
            }
            if (curve.type[j] == "pen") {
                if (basis == "trunc.poly") 
                  ncol.X.val <- deg.val
                if (basis == "tps") 
                  ncol.X.val <- (deg.val - 1)/2
                inst.col.inds <- fc.stt.pos:(fc.stt.pos + ncol.X.val - 
                  1)
                fc.stt.pos <- fc.stt.pos + ncol.X.val
                knots <- object$info$pen$knots[[pen.num]]
                num.knots <- length(knots)
                Z.g.inst <- outer(x.grid, knots, "-")
                if (basis == "trunc.poly") {
                  if (drv == 0) 
                    Z.g.inst <- (Z.g.inst * (Z.g.inst > 0))^deg.val
                  else {
                    if (deg.val >= drv) {
                      mfac <- prod((deg.val - drv + 1):deg.val)
                      Z.g.inst <- mfac * (Z.g.inst * (Z.g.inst > 
                        0))^(deg.val - drv)
                    }
                    else Z.g.inst <- matrix(0, length(x.grid), 
                      length(knots))
                  }
                }
                if (basis == "tps") {
                  if (drv == 0) {
                    Z.g.inst <- abs(Z.g.inst)^deg.val
                    sqrt.Omega <- object$info$trans.mat[[pen.num]]
                    Z.g.inst <- t(solve(sqrt.Omega, t(Z.g.inst)))
                  }
                  else {
                    if (deg.val >= drv) {
                      mfac <- prod((deg.val - drv + 1):deg.val)
                      Z.g.inst <- mfac * (Z.g.inst^(deg.val - 
                        drv - 1) * abs(Z.g.inst))
                      sqrt.Omega <- object$info$trans.mat[[pen.num]]
                      Z.g.inst <- t(solve(sqrt.Omega, t(Z.g.inst)))
                    }
                    else Z.g.inst <- matrix(0, length(x.grid), 
                      length(knots))
                  }
                }
                C.g.inst <- cbind(C.g.inst, Z.g.inst)
                inst.col.inds <- c(inst.col.inds, block.inds[[j + 
                  1]][-(1:ncol.X.val)])
                pen.num <- pen.num + 1
            }
            C.grid[, inst.col.inds] <- C.g.inst
            y.grid <- as.vector(C.grid %*% coefs)
            if (default.ylim) {
                plot.params$ylim$lower[j] <- min(y.grid)
                plot.params$ylim$upper[j] <- max(y.grid)
            }
            if (se == TRUE) {
                se.grid <- sqrt(diag(C.grid %*% cov.mat %*% t(C.grid)))
                lower <- y.grid - 2 * se.grid
                upper <- y.grid + 2 * se.grid
                if (default.ylim) {
                  plot.params$ylim$lower[j] <- min(lower)
                  plot.params$ylim$upper[j] <- max(upper)
                }
                ylim.val <- range(c(lower, upper))
            }
            if (plot.params$plot.it[j] == TRUE) {
                plot(x.grid, y.grid, type = "n", bty = plot.params$bty[j], 
                  main = plot.params$main[j], xlab = plot.params$xlab[j], 
                  ylab = plot.params$ylab[j], xlim = 
c(plot.params$xlim$lower[j], 
                    plot.params$xlim$upper[j]), ylim = 
c(plot.params$ylim$lower[j], 
                    plot.params$ylim$upper[j]))
                if (se == TRUE) {
                  if (shade == FALSE) {
                    lines(x.grid, lower, lty = plot.params$se.lty[j], 
                      lwd = plot.params$se.lwd[j], col = plot.params$se.col[j])
                    lines(x.grid, upper, lty = plot.params$se.lty[j], 
                      lwd = plot.params$se.lwd[j], col = plot.params$se.col[j])
                  }
                  if (shade == TRUE) {
                    mat <- cbind(x.grid, lower, upper)
                    mat <- mat[sort.list(mat[, 1]), ]
                    x.grid <- mat[, 1]
                    lower <- mat[, 2]
                    upper <- mat[, 3]
                    polygon(c(x.grid, rev(x.grid)), c(lower, 
                      rev(upper)), col = plot.params$shade.col[j], 
                      border = FALSE)
                  }
                }
                if ((drv >= 1) & (plot.params$zero.line == TRUE)) 
                  abline(h = 0, err = -1)
                lines(x.grid, y.grid, lty = plot.params$lty[j], 
                  lwd = plot.params$lwd[j], col = plot.params$col[j])
                if (plot.params$jitter.rug == TRUE) 
                  rug.x <- jitter(x.vals[, j])
                if (plot.params$jitter.rug == FALSE) 
                  rug.x <- x.vals[, j]
                rug(rug.x, quiet = 1, col = plot.params$rug.col[j])
            }
        }
    }
    if (krige.present) {
        if (plot.params$plot.image == TRUE) {
            if ((!lin.present) & (!pen.present)) 
                num.curves <- 0
            pixel.info <- get.pixel.info(plot.params)
            on.inds <- pixel.info$on.inds
            off.inds <- pixel.info$off.inds
            image.grid.size <- plot.params$image.grid.size
            num.pix <- image.grid.size[1] * image.grid.size[2]
            num.on.pix <- length(on.inds)
            C.grid <- matrix(rep(ave.vals, num.on.pix), num.on.pix, 
                length(ave.vals), byrow = TRUE)
            z <- rep(0, num.pix)
            X.g.inst <- as.matrix(pixel.info$newdata)
            x1.g.inst <- X.g.inst[, 1]
            x2.g.inst <- X.g.inst[, 2]
            m.krige <- (object$info$krige$degree/2) + 1
            if (m.krige > 2) 
                for (im in 3:m.krige) {
                  X.g.inst <- cbind(X.g.inst, x1.g.inst^(im - 
                    1))
                  if (im > 2) 
                    for (ipow in 2:(im - 1)) X.g.inst <- cbind(X.g.inst, 
                      (x1.g.inst^(im - ipow)) * (x2.g.inst^(ipow - 
                        1)))
                  X.g.inst <- cbind(X.g.inst, x2.g.inst^(im - 
                    1))
                }
            knots <- object$info$krige$knots
            knots.1 <- knots[, 1]
            knots.2 <- knots[, 2]
            num.knots <- length(knots.1)
            dists.g <- outer(x1.g.inst, knots.1, "-")^2
            dists.g <- sqrt(dists.g + outer(x2.g.inst, knots.2, 
                "-")^2)
            prelim.Z.g.inst <- tps.cov(dists.g, m = m.krige, 
                d = 2)
            Z.g.inst <- t(solve(object$info$trans.mat[[num.pen + 
                1]], t(prelim.Z.g.inst)))
            C.g.inst <- cbind(X.g.inst, Z.g.inst)
            inst.col.inds <- block.inds[[num.curves + 2]]
            C.grid[, inst.col.inds] <- C.g.inst
            z[on.inds] <- as.vector(C.grid %*% coefs)
            z[off.inds] <- NA
            z <- matrix(z, image.grid.size[1], image.grid.size[2])
            imageFull(z, plot.params)
        }
    }
    return(list(xval=x.grid,yval=y.grid,se=se.grid))
    invisible()
}
______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to