1

I'm having some issues using a function that should calculate the weighted arithmetic mean in R.

I am using the following function to calculate the weighted arithmetic means for some scores:

candidateScores = function(weight1, weight2, weight3) {
  if(weight1+weight2+weight3 == 1) {
    BobScore = 9*weight1 + 6*weight2 + 4*weight3
    SueScore = 7*weight1 + 7*weight2 + 6*weight3
    HyolynScore = 4*weight1 + 8*weight2 + 8*weight3
    print(paste("Bob's Score: ", BobScore))
    print(paste("Sue's Score: ", SueScore))
    print(paste("Hyolyn's Score: ", HyolynScore))
  } else {
    print("Your weights do not add up to 1.")
  }
}

It is for use with aggregate functions so the weights must total 1, hence the "else" condition. For most values the function works correctly, however for a few value combinations I get the "else" output, despite the weights totally 1.

Some combinations that cause this:

-> candidateScores(weight1 = 0.6, weight2 = 0.3, weight3 = 0.1)

-> candidateScores(weight1 = 0.31, weight2 = 0.59, weight3 = 0.1)

If I change the function to <=1 rather than ==1, it seems to work with these values.

Does anyone know why this might be the case?

Thanks! And I'm brand new to R so apologies if there are mistakes etc!

Phil
  • 7,287
  • 3
  • 36
  • 66
Rosie
  • 11
  • 1

1 Answers1

0

I'm assuming the inconsistency is probably because of the floating cases, as mentioned by @Vinícius Félix. If that is the case, I'm curious to see whether adding all.equal() and adding a small tolerance would fix your problem:

candidateScores = function(weight1, weight2, weight3) {
  if(all.equal(weight1+weight2+weight3, 1, tolerance=1e-8)) {
    BobScore = 9*weight1 + 6*weight2 + 4*weight3
    SueScore = 7*weight1 + 7*weight2 + 6*weight3
    HyolynScore = 4*weight1 + 8*weight2 + 8*weight3
    print(paste("Bob's Score: ", BobScore))
    print(paste("Sue's Score: ", SueScore))
    print(paste("Hyolyn's Score: ", HyolynScore))
  } else {
    print("Your weights do not add up to 1.")
  }
}

PS: With this modification, your function should be able to handle cases where the weights do not add up to exactly 1, but are close enough within the specified tolerance level.

Another option would be using round() instead of all.equal(), and round it for 8 or more decimal cases ex. round(weight1 + weight2 + weight3, 10) == 1

Ruam Pimentel
  • 1,288
  • 4
  • 16
  • Amazing, thank you for your answer! I have only been using R for a couple of weeks and I'm fairly new to programming in general. I'm surprised I've stumbled on a limitation so soon into developing my skills. The "floating point" info explains it well and adding in a small amount of tolerance should definitely fix this. :) Thank you again! – Rosie Dec 12 '22 at 01:05