Using mapply with middle function on matrix
I want to calculate the average of the adjacent values ββin each column (or row) of a matrix (for example, the average from [1,1] and [2,1], [2,1] and [3,1], [3,1] and [4,1]) and apply them to all columns.
I tried to use the mapply function (to avoid using a for loop) to calculate the average of the first two values ββin each column and plan to apply that to the entire matrix row by row. However mapply, which seems to work if I try to sum the values, but not for the average function.
See example below:
x <- matrix(c(NA,rnorm(28),NA), nrow=6, ncol=5)
print(x)
[,1] [,2] [,3] [,4] [,5]
[1,] NA -0.6557176 1.7741320 0.3667700 -0.5548408
[2,] 0.14001643 0.2521062 -0.1295084 -0.4272368 0.7598425
[3,] 0.32123196 0.5736409 0.8618268 2.1535191 0.4686728
[4,] 0.06573949 -1.2101965 -0.4308219 -0.2624877 -0.3751350
[5,] -0.66247996 1.2743463 1.6044236 1.2004990 -0.3283678
[6,] 1.05005260 1.2264607 3.2347421 -0.8113528 NA
mapply(sum, x[1,], x[2,])
[1] NA -0.40361136 1.64462358 -0.06046682 0.20500169
# gives the sum of the input of rows 1 and 2 for each column, as expected
mapply(mean, x[1,], x[2,])
[1] NA -0.6557176 1.7741320 0.3667700 -0.5548408
# gives the actual values across row 1
When using the middle function, the output is represented by the values ββof the first line. I suspect the problem is indexing the correct input values.
source to share
I think this will do what you want:
(head(x, -1L) + tail(x, -1L)) / 2
Produces (using your data with set.seed(1)
):
[,1] [,2] [,3] [,4] [,5]
[2,] NA -0.1665197 -0.11569867 0.8825287 -0.6847630
[3,] -0.2214052 0.6128769 -1.41797023 0.7075613 0.2818485
[4,] -0.3259926 0.6570530 -0.54488448 0.7564393 -0.1059621
[5,] 0.3798261 0.1351965 0.53999865 0.8505568 -0.8132739
[6,] 0.9623943 0.6031964 -0.03056194 0.4283506 NA
tail(x, -1L)
gives a matrix with every row except the first. Thus, the first row of the resulting matrix is ββthe second row of the original, the second is the third, etc. We then add this to the original matrix minus the first row. This is equivalent to adding the second line to the 1st, 3rd and 2nd, etc. Finally, we just divide by two, which gives us the average.
The reason your approach fails is because it mean
only averages its first argument, as opposed to sum
, which sums up all of its arguments:
> args(mean)
function (x, ...)
NULL
> args(sum)
function (..., na.rm = FALSE)
NULL
sum
sums everything ...
, but mean
only takes the average x
, so the second line you pass mean
with mapply
is discarded (or worse, used as an argument trim
, see ?mean
).
source to share