suckrates
suckrates

Reputation: 185

Leave one out for multiple arguments with mapply()?

With a single vector A = c(1,2,3,4,5), I can write

 sapply(A, function(a) mean(A[-a]))

to compute five means: the mean of A without the first element, the mean of A without the second element, etc.

I would like to do leave-one-out operations like this with two or more vectors at the same time. For example, with B <- c(6,7,8,9,10), I thought I could type

myFunc <- function(a, b){return( c(mean(A[-a]), mean(B[-b])) )}
mapply(myFunc, A, B)

but that only computes the leave-one-out means of A:

     [,1] [,2] [,3] [,4] [,5]
[1,]  3.5 3.25    3 2.75  2.5
[2,]  8.0 8.00    8 8.00  8.0

and outputs a row of 8.0s for B. What am I doing wrong?

Upvotes: 2

Views: 103

Answers (3)

Henrik
Henrik

Reputation: 67778

First, instead of looping over vector elements when calculating your mean, you can vectorize your code: (sum(x) - x) / (length(x) - 1). Furthermore, because you have "two or more vectors", you better store them in a list. You can then loop over vectors with lapply.

lapply returns a list. However, if the vectors are of different length, you need to use SIMPLIFY = FALSE in mapply to return a list anyway.

l <- list(A, B)
f <- function(x) (sum(x) - x) / (length(x) - 1)
lapply(l, f)
# [[1]]
# [1] 3.50 3.25 3.00 2.75 2.50
#
# [[2]]
# [1] 8.50 8.25 8.00 7.75 7.50

Upvotes: 1

Clemsang
Clemsang

Reputation: 5481

You can use :

mapply(function(k) c(mean(A[-k]), mean(B[-k])), 1:length(A))

Upvotes: 1

akrun
akrun

Reputation: 887138

In the first vector 'A', the values are the same as the sequence. So, when we index with that value and remove, it remove the corresponding value. In the second vector 'B', it is not the case i.e. B[-6] or B[-7] still gives the whole vector. Instead, loop through the sequence

mapply(myFunc, seq_along(A), seq_along(B))

Upvotes: 1

Related Questions