0

My code below currently reads in a dataset, which I am feeding into the function. It calculates the sum of the values in that column into this.sum. Now I would like to extend the capabilities of this code.

My dataset has lots of 0's, followed by short stretches of values, or "events". I would like to find the number of these "events", based on how many times my data goes from 0 to a value. Also, I would like events which have fewer than five zeroes separating them, to be in the same event.

So, with my dataset below, I would like it to say that "2 events have occurred."

I want to still keep 'this.sum', but would like to now have this.events stored.

I am used to scripting languages like Python and Matlab, and am new to Javascript, so any help is appreciated!

processData: function(data) {

        // convert our data from the file into an array
        var lines = data.replace(/\n+$/, "").split("\n");

        // we have array of strings but need an array of Numbers this should do the trick getting rid of any text and 0 values (source: http://stackoverflow.com/a/26641971)
        lines = lines.map(Number).filter(Boolean);

        // now we find the sum of all of the values in our array. (source: http://stackoverflow.com/a/16751601)
        this.sum = lines.reduce((a, b) => a + b, 0);
        this.sum = this.sum.toFixed(2);
    },

Data:

0
0
0
0
0
0
0
0
0
.256
.369
.598
.145
.695
.984
.259
.368
.352
0
0
0
0
0
0
0
0
0
0
0
0
.256
.369
.598
.145
.695
.984
.259
.368
.352
0
0
0
0
.256
.369
.598
.145
.695
.984
.259
.368
.352

EDIT: The following gave me an incorrect value for ev, regardless of the changes I made to count (changed from 5, to 10, to 15) (my dataset contains different numbers than the dataset given above.) But as I changed the value to 500, it dropped, so I went higher to 12,000 and it gave me the value for this.events that I was expecting.

processData: function(data) {

        // convert our data from the file into an array
        var lines = data.replace(/\n+$/, "").split("\n");

var ev = 0; // the event counter (initialized to 0)
for(var i = 0, count = 0; i < data.length; i++) { // 'count' will be the counter of consecutive zeros
  if(lines[i] != 0) { // if we encounter a non-zero line
    if(count > 5) ev++; // if the count of the previous zeros is greater than 5, then increment ev (>5 mean that 5 zeros or less will be ignored)
    count = 1; // reset the count to 1 instead of 0 because the next while loop will skip one zero
    while(++i < lines.length && lines[i] != 0) // skip the non-zero values (unfortunetly this will skip the first (next) zero as well that's why we reset count to 1 to include this skipped 0)
      ;
  }
  else // if not (if this is a zero), then increment the count of consecutive zeros
    count++;
}
this.events = ev;

        // we have array of strings but need an array of Numbers this should do the trick getting rid of any text and 0 values (source: http://stackoverflow.com/a/26641971)
        lines = lines.map(Number).filter(Boolean);

        // now we find the sum of all of the values in our array. (source: http://stackoverflow.com/a/16751601)
        this.sum = lines.reduce((a, b) => a + b, 0);
        this.sum = this.sum.toFixed(2);
    },
Gary
  • 2,137
  • 3
  • 23
  • 41
  • So what have you tried so far, and where did you get stuck? – RobG Feb 09 '17 at 01:37
  • Are you sure it will say 2 not 3? According to your example the change from 0s to non-0s occured 3 times! – ibrahim mahrir Feb 09 '17 at 01:39
  • 1
    @ibrahimmahrir—the second change has less than five zeros between the non–zero values. – RobG Feb 09 '17 at 01:40
  • @ibrahimmahrir—yep, brain is a little slow today… one liner: `var events = data.replace(/^(0\n)+|\n/g,'').split(/00000+/).map(function(s){ return s.replace(/(\d)\.(\d)/g,'$1\n.$2').replace(/0/g,'\n0'); });`. Probably can be done with fewer operations. – RobG Feb 09 '17 at 02:05

1 Answers1

1
var ev = 0; // the event counter (initialized to 0)
for(var i = 0, count = 0; i < lines.length; i++) { // 'count' will be the counter of consecutive zeros
  if(lines[i] != 0) { // if we encounter a non-zero line
    if(count > 5) ev++; // if the count of the previous zeros is greater than 5, then increment ev (>5 mean that 5 zeros or less will be ignored)
    count = 1; // reset the count to 1 instead of 0 because the next while loop will skip one zero
    while(++i < lines.length && lines[i] != 0) // skip the non-zero values (unfortunetly this will skip the first (next) zero as well that's why we reset count to 1 to include this skipped 0)
      ;
  }
  else // if not (if this is a zero), then increment the count of consecutive zeros
    count++;
}
this.events = ev;
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
  • Thanks! I'll give this a go :) – Gary Feb 09 '17 at 02:40
  • This is returning a value of `ev` equal to 0, when my data definitely has events to tally. My data file is just a .csv with a header and rows of data underneath. Any thoughts on things to look for to debug? – Gary Feb 09 '17 at 19:17
  • I had to change the 5 to 12,000 in order to be an accurate number of events. Could I be off by a factor of 1000 somewhere? – Gary Feb 09 '17 at 19:34
  • @Gary I don't fully understand! What seems to be the problem? – ibrahim mahrir Feb 09 '17 at 20:06
  • I added an edit, so hopefully you can understand better :) – Gary Feb 09 '17 at 20:57
  • @Gary try and put a `console.log(lines.length);` before `var ev = 0;`. What does it log? – ibrahim mahrir Feb 09 '17 at 21:00
  • It returned 79722, which is the number of seconds that have elapsed since the start of the day. Each row in my dataset corresponds to data taken every second. – Gary Feb 10 '17 at 02:29
  • 1
    @Gary **ooooops** I've just noticed `for(var i = 0, count = 0; i < data.length; i++)`. It should be `for(var i = 0, count = 0; i < lines.length; i++)`, we're looping through `lines` not `data`. I hope that fixes the problem and sorry for such a stupid mistake!!! – ibrahim mahrir Feb 10 '17 at 04:44
  • Thanks Ibrahim! I will try this in the afternoon and let you know how it goes! – Gary Feb 10 '17 at 13:16
  • One more question related to this post. I am now trying to count an event, also based on how long it is, not just the number of zeros in between. I posted it here: http://stackoverflow.com/questions/42184125/counting-the-number-of-events-in-a-column-of-data-of-a-certain-length – Gary Feb 13 '17 at 14:10