3

I want to multiply and then sum the unique pairs of a vector, excluding pairs made of the same element, such that for c(1:4):

(1*2) + (1*3) + (1*4) + (2*3) + (2*4) + (3*4) == 35

The following code works for the example above:

x <- c(1:4)
bar <- NULL
for( i in 1:length(x)) { bar <- c( bar, i * c((i+1) : length(x)))}
sum(bar[ 1 : (length(bar) - 2)])

However, my actual data is a vector of rational numbers, not integers, so the (i+1) portion of the loop will not work. Is there a way to look at the next element of the set after i, e.g. j, so that I could write i * c((j : length(x))?

I understand that for loops are usually not the most efficient approach, but I could not think of how to accomplish this via apply etc. Examples of that would be welcome, too. Thanks for your help.

Henrik
  • 65,555
  • 14
  • 143
  • 159
et70
  • 33
  • 4
  • Possible dupe: http://stackoverflow.com/questions/18899332/r-pairwise-product. Except for the (trivial) `sum` in the end, and that OP seems to look also for an explanation for the failed loop (XY-problem). – Henrik Aug 08 '15 at 12:59

1 Answers1

5

An alternative to a loop would be to use combn and multiply the combinations using the FUN argument. Then sum the result:

sum(combn(x = 1:4, m = 2, FUN = function(x) x[1] * x[2]))
# [1] 35

Even better to use prod in FUN, as suggested by @bgoldst:

sum(combn(x = 1:4, m = 2, FUN = prod))
Henrik
  • 65,555
  • 14
  • 143
  • 159
  • 1
    if you wanted to extend to encapsulate the "unique pairs" comment, you could do something like: FUN = function(x) X[1] * X[2] * (X[1] != X[2]) – RichAtMango Aug 08 '15 at 11:26
  • 2
    Good solution, +1. I'd only suggest replacing the `function(x) x[1] * x[2]` with [`prod`](https://stat.ethz.ch/R-manual/R-devel/library/base/html/prod.html), which does the same thing. – bgoldst Aug 08 '15 at 11:30
  • 1
    @RichAtMango I am not quite sure I follow you. Have a look at `combn(1:4, 2)`. – Henrik Aug 08 '15 at 11:31
  • 1
    @henrik have a look at `combn(c(1, 2, 3, 3, 4), 2)`. The original question spoke about "unique values", so should columns 2 & 3 of this result be counted twice? – RichAtMango Aug 08 '15 at 11:47
  • 1
    @RichAtMango Now I follow you. Thanks for the clarification. I was (possibly erroneously) assuming unique elements in the input vector (let OP clarify). If this is not the case, your suggestion makes sense. Or perhaps just wrap the input vector in `unique`? – Henrik Aug 08 '15 at 11:52
  • yeah - wrappinng input vector inn `unique` would do same thing – RichAtMango Aug 08 '15 at 11:55