Assignment #11: Debugging and Defensive Programming in R

 Debugging and Defensive Programming in R

In this assignment, the goal is to reproduce an error, diagnose the issue, correct the code, and apply defensive programming techniques.


Reproducing the Error

I began by running the provided buggy function on a test matrix:

set.seed(123)

test_mat <- matrix(rnorm(50), nrow = 10)


tukey_multiple(test_mat)


This produced the following warning message:

Warning message:

In outliers[, j] && tukey.outlier(x[, j]) :

  'length(x) = 10 > 1' in coercion to 'logical(1)'



Diagnosing the Bug

The issue comes from this line in the function:

outliers[, j] <- outliers[, j] && tukey.outlier(x[, j])


The operator && only evaluates the first element of a logical vector. However, the function tukey.outlier() returns a logical vector corresponding to each row of the matrix.

Because of this, only the first value was being checked, which caused incorrect behavior and triggered a warning.

To correctly compare all elements, the function must use the element-wise logical AND operator &, which evaluates each position in the vector.


Fixing the Code

I corrected the bug by replacing && with &:

outliers[, j] <- outliers[, j] & tukey.outlier(x[, j])


This ensures that the comparison is applied across all rows in the matrix.


Corrected Function

corrected_tukey <- function(x) {

  if (!is.matrix(x)) {

    stop("x must be a matrix.")

  }

  if (!is.numeric(x)) {

    stop("x must be a numeric matrix.")

  }


  outliers <- array(TRUE, dim = dim(x))

  

  for (j in seq_len(ncol(x))) {

    outliers[, j] <- outliers[, j] & tukey.outlier(x[, j])

  }


  outlier.vec <- logical(nrow(x))

  

  for (i in seq_len(nrow(x))) {

    outlier.vec[i] <- all(outliers[i, ])

  }


  return(outlier.vec)

}



Validating the Fix

After applying the fix, I re-ran the function:

corrected_tukey(test_mat)


The function returned a logical vector of length 10 without any warnings:

[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE


This confirms that the function is now working as intended.


Defensive Programming Enhancements

To make the function more robust, I added input validation checks:

  • Ensured the input is a matrix

  • Ensured the matrix is numeric

If these conditions are not met, the function stops with a clear error message.


Conclusion

This debugging exercise highlighted the importance of understanding the difference between && and & in R. While && is useful for single logical comparisons, it is not appropriate for vectorized operations. Using the correct operator (&) allowed the function to properly evaluate all elements and produce accurate results.


https://github.com/ygraham-code/r-programming-assignments.git

Comments

Popular posts from this blog

Module # 6 Doing math in R part 2