Depends on what you decide to be integer. Usually you don't need your integers to be stored as an objects of class integer
:
Integer vectors exist so that data can be passed to C or Fortran code which expects them, and so that (small) integer data can be represented exactly and compactly.
So, 3
is integer which is represented in R as numeric
(try class(3)
to see that). So I think, we don't need to check class of the values passed to your function, but rather check if those numbers are whole numbers with some level of tolerance.
sum_int <- function(..., tol = .Machine$double.eps^.5){
if(any(abs(round(c(...)) - c(...)) > tol)){
return(NA)
}
return(sum(round(c(...))))
}
sum_int(1, 2, 3 + 1e-7)
#NA
sum_int(1, 2, 3 + 1e-15)
#6
sum_int(1, 2, 3 + 1e-15, tol = 0)
#NA
sum_int(1, 2, 3.1, tol = .02)
#NA
sum_int(1, 2, 3.1, tol = .2)
#6
At the first step we grab the list of all arguments passed into the sum_int()
. To find if those values are integers we use predefined or defined by user tolerance level (tol
is defined the same way as it shown in ?is.integer
examples). After that we round our numeric values, to make them whole numbers, and to find fractional parts of those values, as absolute difference between whole parts of the arguments, and arguments themselves. If any of the fractional parts exceed the tolerance level - we return NA. Otherwise we return sum of whole parts of those values.