Skip to content
Prev 228489 / 398500 Next

sweep / mapply question

Dear list,

I have a matrix, spc, that should row-wise be interpolated:

E.g.

spc <- matrix (1:1e6, ncol = 250, nrow = 4000, byrow = TRUE)
spc [1:10, 1:10]
shifts <- seq_len (nrow (spc))
wl <- seq_len (ncol (spc))

interpolate <- function (spc.row, shift, wl)
   spline (wl + shift, spc.row, xout = wl, method = "natural")$y

interpolate (spc [1,], shift = shifts [1], wl = wl) [1:10] # works


naively, I wanted to use sweep to vectorize this:

sweep (spc, 1, shifts, interpolate, wl = wl)

This doesn't work, as sweep basically repeats the STATS in the correct way, and 
hands two matrices (arrays) to the function. While this is fine and fast for + - 
* / etc., but doesn't help my interpolation.


Of course, I can calculate what I need:

system.time (
t (mapply (interpolate, as.data.frame (t (spc)),
	                shift = shifts,
            MoreArgs= list (wl = wl)))
)

system.time (
sapply (1 : nrow (spc),
         function (i) interpolate (spc [i, ], shifts [i], wl = wl))
)

tmp <- spc
system.time ({
for (i in 1 : nrow (spc))
  tmp [i,] <- interpolate (spc [i, ], shifts [i], wl = wl)
})

On my computer the for loop is fastest (slightly faster than sapply, a bit less 
than half of the time of mapply).

However, as I expect this to be a fairly common situation,

I want to share this experience, and
the question is: is there a better / faster / nicer / more elegant way to do this?

Comments?

Thanks,

Claudia