Dealing with NaN in Tables

This is a test sketch to understand how to deal with empty cells in a table for a much bigger project. I want to be able, in this example, to average each column based on age (1-3, each in it's own index for that column)

Table table;

float[] num1 = new float[3];
float[] num2 = new float[3];
float[] num3 = new float[3];

void setup() {
  table = loadTable("testSheet.csv", "header");

  for (TableRow row : table.rows ()) {
    int a = row.getInt("Age");
    float one = row.getFloat("Num1");
    float two = row.getFloat("Num2");
    float three = row.getFloat("Num3");

//    if (one > 0) {                        // Uses an if statement to check if each value is not a null value
//      num1[a-1] += one/3;
//    }
//    if (two > 0) {
//      num2[a-1] += two/3;
//    }
//    if (three > 0) {
//      num3[a-1] += three/3;
//    }
//  }
      num1[a-1] += one/3;

      num2[a-1] += two/3;

      num3[a-1] += three/3;

  }

  println (num1[0], num1[1], num1[2]);
  println (num2[0], num2[1], num2[2]);
  println (num3[0], num3[1], num3[2]);
}

When I output the averages, I get "NaN" and want to know if there's a way I can tell Processing to ignore anything that isn't a number. I'd rather not manually put if statements around each assignment, which I have commented out.

Much appreciated!

Answers

  • The short answer is no, there isn't a magic ignorNaN() function or anything. You have to process your data.

  • edited February 2015

    you could have the if statement in a function and thus make it simpler:

    float NaN_Stopper(float valueFromTable) {
        if (valueFromTable > 0) {
          return valueFromTable;
        }
        else {
          return 0;
        }
    }
    

    and then

    num1[a-1] += NaN_Stopper(one) / 3;
    
  • That assumes the OP wants to treat NaN as zero instead of skipping over it.

    Should the average of (10 + 20 + NaN) be 10, or should it be 15?

  • edited February 2015

    You can weed out NaN by comparing the value with itself. NaN has the special property of not being equal to itself:

    void setup() {
      size(100, 100);
    
      // 0.0 / 0.0 is NaN
      float foo = 0.0/0.0;
      println(foo);
    
      // NaN is not equal NaN, this prints false
      println(foo == foo);
    
      exit();
    }
    

    Edit: Although you still will have to decide what the average should be after identifying a NaN

  • Thank you for your feedback! I have changed my floats to Floats in order to check for NaN:

    if (!one.isNaN()){
          num1[a-1] += one/3;
        }
    

    For the points Kevin brought up-I can't treat the NaN as 0 (it would impact averages and other calculations for visualizatoin), and the average of (10 + 20 + NaN) would be 10

  • I have changed my floats to Floats in order to check for NaN:

    Note that this doesn't give you anything that your original if statements didn't already handle. The point is that you're going to have to use if statements no matter which approach you take.

    the average of (10 + 20 + NaN) would be 10

    You mean 15?

  • edited February 2015

    he means, it would (falsely) be 10 when he treated NaN as 0 [10+20+0 divided by 3]

    it's his closing bracket ) coming too early in the sentence

    ;-)

  • it's his closing bracket ) comes too early in the sentence

    Good thing we're not programming in lisp!

Sign In or Register to comment.