3

I've encountered a simple question but failed to write the code. Grateful if you can help me.

The question: Create a function that will return the sum of 2 integers.

My code:

q1 <- function(a, b) {
  if (a == as.integer(a)) {
    if (b == as.integer(b)) {
      result1 <- a + b
    }
  }
} else {
  result1 <- NA
  result1
}

q1(3,6) - suppose it returns 9

q1(3.1,6) - suppose it returns NA

BTW, why can I not write the syntax in this way? if(is.integer(a) = TRUE){

NelsonGon
  • 13,015
  • 7
  • 27
  • 57
ronzenith
  • 341
  • 3
  • 11
  • Thanks. Why is.numeric is better than as.integer? The question requires a and b to be integer.... – ronzenith Jul 27 '19 at 06:43
  • 1
    Do you need your function to sum only `integer`s as an *R objects* or, your function is supposed to sum only *integers* i.e. whole numbers? – utubun Jul 27 '19 at 07:30

4 Answers4

1

This uses a function (testInteger) in this answer, slightly edited. It checks if a value is TRUE with the now recommended isTRUE().

testInteger <- function(x){
  test <- all.equal(x, as.integer(x), check.attributes = FALSE)
  isTRUE(test)
}

q1 <- function(a, b) {
  if (testInteger(a) && testInteger(b)) {
    a + b
  } else {
    NA
  }
}

q1(3, 6)    # returns 9
q1(3.1, 6)  # returns NA
Rui Barradas
  • 70,273
  • 8
  • 34
  • 66
1

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.

utubun
  • 4,400
  • 1
  • 14
  • 17
0

You had missplaced some brackets and you were not returning anything, check this:

q1 <- function(a,b){
if (a == as.integer(a)){
    if (b == as.integer(b)){
      result1 <- a + b
    }
  }
 else {
  result1 <- NA
 }
  return(result1);
}
user123
  • 175
  • 4
  • 16
0

If you want your function to only sum() integers, as in the R object.

Intsum <- function(a,b){
    if(is.integer(a) & is.integer(b) == TRUE){
      return(sum(a,b))
  }
  else {
     return(NA)
  }
}
fabla
  • 1,806
  • 1
  • 8
  • 20