Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calculations: Update First * and Last * reducers to exclude NaNs #77323

Merged
merged 7 commits into from
Oct 30, 2023

Conversation

nmarrs
Copy link
Contributor

@nmarrs nmarrs commented Oct 27, 2023

What is this feature?

Exclude NaN values as part of Last * and First * reducers.

NaN.handling.mov

NaN_-1698445566753.json.txt

Why do we need this feature?

NaN is not typically considered a "valid" value and so excluding it makes sense through these reducers as they are designed to return either the first or last "valid" value.

Who is this feature for?

Users that want to receive the first or last "valid" value in their data.

Which issue(s) does this PR fix?:

Fixes #59862

Special notes for your reviewer:

Please check that:

  • It works as expected from a user's perspective.
  • If this is a pre-GA feature, it is behind a feature toggle.
  • The docs are updated, and if this is a notable improvement, it's added to our What's New doc.

@nmarrs nmarrs added add to changelog area/panel/data Common panel data querying & processing no-backport Skip backport of PR labels Oct 27, 2023
@nmarrs nmarrs added this to the 10.3.x milestone Oct 27, 2023
@nmarrs nmarrs requested a review from a team October 27, 2023 22:39
@nmarrs nmarrs self-assigned this Oct 27, 2023
@nmarrs nmarrs requested a review from a team October 27, 2023 22:39
@nmarrs nmarrs requested review from oscarkilhed and mdvictor and removed request for a team October 27, 2023 22:39
@nmarrs nmarrs changed the title Calculations: Update First * and Last * reduces to also exclude NaNs Calculations: Update First * and Last * reduces to exclude NaNs Oct 27, 2023
@@ -418,7 +418,7 @@ function calculateFirstNotNull(field: Field, ignoreNulls: boolean, nullAsZero: b
const data = field.values;
for (let idx = 0; idx < data.length; idx++) {
const v = data[idx];
if (v != null && v !== undefined) {
if (v != null && v !== undefined && !isNaN(v)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably if (v != null && !Number.isNaN(v))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah good catch - Number.isNaN doesn't infer that value is number and instead is unknown

Currently working on adding a test and the reduceFields function isn't playing nicely and still is returning NaN instead of the expected valid value in the test suite 🙃

},
];

const stats = reduceField({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stats returns:

{
        sum: 200,
        max: 200,
        min: 200,
        logmin: 200,
        mean: 200,
        last: NaN,
        first: NaN,
        lastNotNull: 200,
        firstNotNull: 200,
        count: 3,
        nonNullCount: 1,
        allIsNull: false,
        allIsZero: false,
        range: 0,
        diff: 0,
        delta: 0,
        step: null,
        diffperc: 0,
        previousDeltaUp: true
}

@@ -320,8 +320,8 @@ export function doStandardCalcs(field: Field, ignoreNulls: boolean, nullAsZero:

calcs.count++;

if (currentValue != null) {
// null || undefined
if (currentValue != null && !Number.isNaN(currentValue)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little scared of modifying the doStandardCalcs function but this seems reasonable 🤷

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryantxu this is a change I'm a little worried about in this PR (modifying doStandardCalcs function) - does this seem reasonable?

},
{
data: [NaN, NaN, NaN], // All NaN
result: null,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we want special handling in this case (i.e. if all NaN return NaN vs null)

Comment on lines 421 to 422
if (v != null && v !== undefined && !isNaN(v)) {
return { firstNotNull: v };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the undefined part required? I think != null covers both null and undefined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

foo != null will check if foo is either null or undefined so we should be good with this simplification 👍

@leeoniya
Copy link
Contributor

we could go one step further and also omit Infinity and -Infinity by switching to Number.isFinite() for the whole condition. 🤔

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite

@ryantxu
Copy link
Member

ryantxu commented Oct 29, 2023

go one step further

I think that may be one step too far, but I do not feel too strongly

@nmarrs nmarrs changed the title Calculations: Update First * and Last * reduces to exclude NaNs Calculations: Update First * and Last * reducers to exclude NaNs Oct 30, 2023
@nmarrs
Copy link
Contributor Author

nmarrs commented Oct 30, 2023

we could go one step further and also omit Infinity and -Infinity by switching to Number.isFinite() for the whole condition. 🤔

I don't feel super strongly on this either way - though I am not informed on use cases where seeing +/- inf makes sense. Maybe for now we could move forward with just avoiding NaN and see what user sentiment / feedback is for that initial change? What do you think @leeoniya?

@nmarrs nmarrs merged commit 40df27a into main Oct 30, 2023
20 checks passed
@nmarrs nmarrs deleted the calculations-last-non-null-update-NaN-handling branch October 30, 2023 17:33
@aangelisc aangelisc modified the milestones: 10.3.x, 10.2.3 Dec 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
add to changelog area/frontend area/panel/data Common panel data querying & processing no-backport Skip backport of PR type/docs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Corrected NaN behaviour on histogram_quantile causes "last non-null value" to not work as expected
4 participants