I'm running a sensitivity analysis for a multi-criteria decision model. The model is run in R, using the package MCDM. A key component of the model is that it relies on a user-given set of weights that must sum to 1. I am working with weight preferences that originally did not sum to 1 but which I normalized to sum to 1.
weights <- data.frame("w1"=0.03125, "w2"=0.53125, "w3"=0.84375, "w4"=0.21875, "w5"=0.46875, "w6"=0.28125, "w7"=0.96875)
normal_weights <- weights/rowSums(weights)
When I check to confirm that the new weights sum to 1, R confirms they do...
rowSums(normal_weights)
...returns a "1".
However, when I then run the model, I then get the package-specific error that the weights do not sum to 1.
Based on trying to troubleshoot this problem myself, I'm guessing it has something to do with:
- The weights are stored as doubles
- Usually this is fine as 16ish digits past the decimal place is more than needed...but not always
- rowSums doesn't actually return true "1" so if there's a slight precision issue with one set of weights, I don't notice it until I run the model
- The error occurs
Is this what is probably going on? And if so, how do I fix it? Is there a way to maintain precision? A better way to normalize that won't cause this issue?
Edit: I understand that the R Q&A "Why are these numbers not equal?" answers why R does this; but, that post does not answer my question of what are some workarounds to deal with this issue, considering I cannot change package I'm working with?
this is quite normal, it is very difficult to check whether a number is 1. just because R prints 1 it does not mean it is exactly one. in fact you can easily see that
and in fact you can see that
so I would do two things:
1) establish that the weights sum up to 1 with a reasonable accuracy, something like 1e-8 (this really depends on your problem)
2) to get around the error just define the last element of normal_weights as 1 - the sum of the other ones:
I guess the MCMC function you are using as an x == y statement somewhere, it would have probably been better if they had a tolerance test, but that is another story.