0

I think I am getting crazy.

In the following computations, I need to make sure that my proportions equals 100.

I need

sum(res$percBas, res$percInt, res$percTop) == 100

R returns FALSE and I have no clue why! They have the same class and the value of the sum is 100 from the data I provided below. The proportion are calculated as follows:

res$percBas = (res$nBas/res$S)*100
res$percTop = (res$nTop/res$S)*100
res$percInt = (res$nInt/res$S)*100

Is it because nTop, nBas, nInt are integers? Though the proportions are numeric...

Output stored for now in a list:

res = list(S = 43L, L = 252, Z = 5.86046511627907, C = 0.136289886425095, 
G = 6.81081081081081, GenSD = 1.10870900316409, V = 6.14634146341463, 
VulSD = 0.87450656075054, path = 3, dist = 1.41414141414141, 
degc.tot = 0.259353741496599, cloc.tot = 0.502648845059257, 
betc = 0.0103169994284977, MxSim = 0.565777991877899, meanTL = 2.31254748158818, 
maxTL = 3.46153846153846, nBas = 6L, percBas = 13.953488372093, 
nTop = 2L, percTop = 4.65116279069767, nInt = 35L, percInt = 81.3953488372093)
Pierre O
  • 131
  • 6
  • 2
    Trying to get floating point numbers to exactly match is a dangerous game. The safer alternative here is `all.equal(sum(res$percBas, res$percInt, res$percTop), 100)` – MrFlick Feb 27 '20 at 17:24
  • [Relevant?](https://stackoverflow.com/a/47222009/8245406) More or less the same idea is [this function `zeq`](https://stackoverflow.com/a/47221898/8245406). – Rui Barradas Feb 27 '20 at 17:36
  • 1
    @RuiBarradas I think that is exactly what `dplyr::near()` does as well. –  Feb 27 '20 at 17:43
  • The thing I don't get is why it is "near 100" and not 100 exactly. nTop+nBas+nInt should be equal to S otherwise it means 1 or more species are not included. Which here would be problematic. – Pierre O Feb 28 '20 at 07:53
  • It's floating point precision. Perhaps read on the topic a bit. It's not you - its the computer. In your example, remove the `* 100` from each percent calculation. You see that if you do that they will `== 1`. When you multiple by 100, you lose a minuscule amount of precision out to the 16th decimal place, as you can see in my answer. This is the case in this example, but might not always be. –  Feb 28 '20 at 15:12

1 Answers1

3

It is a numeric precision thing.

> options(digits= 16)
> sum(res$percBas, res$percInt, res$percTop)
[1] 99.99999999999997

So you would need to round the sum and then check for equality.

  • I thought of that but since the sum of top+int+bas equals S, why wouldn't it be 100% in the proportion? If the proportions are not equal to 100 that means there is a species missing somewhere. – Pierre O Feb 28 '20 at 07:51