0

Say I have a condition that if a number ends with.00 add 2 to it and if a number ends with.99 add 3 to it. So if I had 5.00 and 5.99, I want to write a nested if statement that would allow me to add the right value to the original number based on its ending.

How to do that in R (or python)?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Ef. O
  • 33
  • 1
  • 4
  • 2
    what do you mean by right value? so do you need 7.00 and 8.99 as your answer? – Onyambu Aug 10 '18 at 16:01
  • What form is your number in? Note that if it's a float, your representation is not guaranteed to have the exact value that you expect. – Prune Aug 10 '18 at 16:05
  • @onyambu, by "right value" I meant adding the corresponding value, so either the 2 or the 3 based on the ending of the original number. – Ef. O Aug 10 '18 at 16:20

4 Answers4

1

Due to floating point precision, you will need to round your numbers to two decimals as values such as 5.99 cannot be represented exactly. This means a value such as 5.9921875 will have to fulfill your criterion as finishing with 0.99.

If you are fine with that, using Python's Format Specification Mini-Language will round implicitly and allow to extract the required decimals.

def get_decimals(num, n=2):
    return '{0:.2f}'.format(num)[-2:]

def func(num):
    decs = get_decimals(num)

    if decs == '00':
        return num + 2
    elif decs == '99':
        return num + 3
    else: return num
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
0

In python.

def func(num):
    if round(num, 2) - int(num) < 0.001:
        return num + 2
    elif round(num, 2) - int(num) > 0.989:
        return num + 3 
    return num

You can round the number to 2 decimal places, subtract it's integer component, then round the result to check if it is close to 0.00 or 0.99. Simply checking if the result before rounding is 0.00 or 0.99 is unreliable because of floating point numbers.

modesitt
  • 7,052
  • 2
  • 34
  • 64
0

It seems there are other values in your list/vector you need to deal with. I will give a vectorized format:

in R:

data = c(5.00,5.99,5.61)
mm = function(x){
  x = round(x,2)
  y = x-as.integer(x)
  ifelse(round(y-0.00,2)==0, x+2,ifelse(round(y-0.99,2)==0,x+3,x))
} 

mm(data)
[1] 7.00 8.99 5.61

In Python: vectorized format with numpy module

import numpy as np
x = np.array([5.00,5.99,5.61])
def mm(x):
    x = np.round(x,2)
    y = x - np.array(x,dtype = 'i')
    return np.where(np.round(y-0.00,2)==0, x+2,np.where(np.round(y-0.99,2)==0,x+3,x))

mm(x)
array([7.  , 8.99, 5.61])
Onyambu
  • 67,392
  • 3
  • 24
  • 53
0

In R we can do

v1 + (floor(v1) != v1) + 2
#[1] 7.00 8.99

If we are looking for last two numeric elements

v2 <- sub(".*(.{2})$", "\\1", sprintf('%0.2f', v1))
ifelse(v2 == "00", v1 + 2, ifelse(v2 == "99", v1 + 3, v1))
#[1] 7.00 8.99

data

v1 <- c(5, 5.99)
akrun
  • 874,273
  • 37
  • 540
  • 662