[R] integration problem
Martin Maechler
maechler at stat.math.ethz.ch
Wed Oct 27 10:02:34 CEST 2004
>>>>> "Sundar" == Sundar Dorai-Raj <sundar.dorai-raj at pdf.com>
>>>>> on Tue, 26 Oct 2004 11:19:36 -0500 writes:
Sundar> Christoph Scherber wrote:
>> Dear R users,
>>
>> I have spectral data (say, wavelength vs. extinction coefficient) for
>> which I´d like to calculate an integral (i.e. the area underneath the
>> curve).
>>
>> Suppose the (artificial) dataset is
>>
>> lambda E
>> 1 2
>> 2 4
>> 3 5
>> 4 8
>> 5 1
>> 6 5
>> 7 4
>> 8 9
>> 9 8
>> 10 2
>>
>>
>>
>> How can I calculate an integral for these values using R?
>>
>> Many thanks for any help!
>> Regards
>>
>> Christoph
>>
Sundar> Hi Christoph,
Sundar> You can write some code to do trapezoidal integration or use ?approx
Sundar> in the following manner:
Sundar> f <- function(xnew, x, y) approx(x, y, xnew)$y
Sundar> integrate(f, min(x$lambda), max(x$lambda), x = x$lambda, y = x$E)
Sundar> where `x' is your data above. Using approx is
Sundar> perhaps overkill but it works. A better solution
Sundar> would be to use trapezoids or perhaps piecewise
Sundar> linear integration. I don't know of a package that
Sundar> has the latter approaches off the top of my head but
Sundar> that doesn't mean they doesn't exist somewhere.
And then, it mighgt be slightly more satisfactory to use
spline() instead of approx() {smooth interpolation instead of linear}.
However, this is exactly an example where
approxfun() is much nicer than approx() and
splinefun() is much nicer than spline() :
I here give a script {output in comments}:
x <- data.frame(lambda = 1:10, E = c(2,4,5,8,1, 5,4,9,8,2))
## Sundar's proposal
f <- function(xnew, x, y) approx(x, y, xnew)$y
integrate(f, min(x$lambda), max(x$lambda), x = x$lambda, y = x$E)
##--> 46 with absolute error < 0.0047
## Using the *fun() version
f2 <- approxfun(x$lambda, x$E)
## or even
f2 <- approxfun(x) # does work: 2-column data frame or matrix
integrate(f2, min(x$lambda), max(x$lambda))
## same answer as above
f3 <- splinefun(x$lambda, x$E)
integrate(f3, min(x$lambda), max(x$lambda))
##--> 46.98437 with absolute error < 0.0046
## Note that you can do more than just integrate them:
plot(x, type = "b")
curve(f2(x), add = TRUE, col=2)
curve(f3(x), add = TRUE, col=3)
f4 <- splinefun(x$lambda, x$E, method ="natural")
curve(f4(x), add = TRUE, col=4)# not much difference
###-----
Further note, that only in R-patched (or R-devel),
we can also use 'splinefun(x)'
directly instead of 'splinefun(x$lambda, x$E)'.
Martin Maechler, ETH Zurich
More information about the R-help
mailing list