Dataframe (#576)

* initial dataframe commit

* initial dataframe port of core app

* rename variables for clarity

* remove unused import

* comment out unused code

* fix array handling bug in crossfilter dimension creation

* allow creation of empty dataframes

* handle non-existent columns

* handle non-existent columns

* revise tests for new dataframe

* comments for clarity

* comments for clarity

* generate bulk add placeholder with real gene names

* fix bug in gene name adding

* more dataframe unit tests

* fix bug - subset from current world, not universe

* put cut and pasted code into a single function

* improve caching of crossfilter

* remove cascading update bug from graph

* more performance work

* improve state handling for scatterplot

* performance optimization of critical path

* add column summarization

* dataframe utils

* add callOnceLazy

* fix tests

* minor updates found during review

* fix misspelling

* remove RESTv02 from function names

* comment cleanup

* cut/icut col parameter defaults to null

* break up large test

* improve tests and comments on dataframe at/has functions
This commit is contained in:
Bruce Martin
2019-02-22 11:31:34 -08:00
committed by GitHub
parent 57c4e9ff33
commit 6b33315cbe
29 changed files with 1798 additions and 611 deletions
@@ -1,4 +1,9 @@
import summarizeAnnotations from "../../../src/util/stateManager/summarizeAnnotations";
import * as Dataframe from "../../../src/util/dataframe";
function float32Conversion(f) {
return new Float32Array([39.3])[0];
}
describe("summarizeAnnotations", () => {
const schema = {
@@ -20,7 +25,8 @@ describe("summarizeAnnotations", () => {
};
test("empty test", () => {
const summary = summarizeAnnotations(schema, [], []);
const df = Dataframe.Dataframe.empty();
const summary = summarizeAnnotations(schema, df, df.clone());
expect(summary).toEqual(
expect.objectContaining({
obs: {
@@ -69,18 +75,27 @@ describe("summarizeAnnotations", () => {
});
test("simple test", () => {
const obsAnnotations = [
{
__index__: 0,
name: "n1",
nameString: "hi",
nameBoolean: true,
nameFloat32: 39.3,
nameInt32: 99,
nameCategorical: 1
}
];
const varAnnotations = [];
const obsAnnotations = new Dataframe.Dataframe(
[1, 6],
[
["n1"],
["hi"],
[true],
new Float32Array([39.3]),
new Int32Array([99]),
[1]
],
null,
new Dataframe.KeyIndex([
"name",
"nameString",
"nameBoolean",
"nameFloat32",
"nameInt32",
"nameCategorical"
])
);
const varAnnotations = Dataframe.Dataframe.empty();
const summary = summarizeAnnotations(
schema,
@@ -105,7 +120,13 @@ describe("summarizeAnnotations", () => {
},
nameFloat32: {
categorical: false,
range: { min: 39.3, max: 39.3, nan: 0, ninf: 0, pinf: 0 }
range: {
min: float32Conversion(39.3),
max: float32Conversion(39.3),
nan: 0,
ninf: 0,
pinf: 0
}
},
nameInt32: {
categorical: false,
@@ -124,36 +145,27 @@ describe("summarizeAnnotations", () => {
});
test("multi test", () => {
const obsAnnotations = [
{
__index__: 0,
name: "n0",
nameString: "hi",
nameBoolean: false,
nameFloat32: 39.3,
nameInt32: 99,
nameCategorical: 1
},
{
__index__: 1,
name: "n1",
nameString: "hi",
nameBoolean: true,
nameFloat32: 39.3,
nameInt32: 99,
nameCategorical: false
},
{
__index__: 2,
name: "n2",
nameString: "bye",
nameBoolean: true,
nameFloat32: 0,
nameInt32: 99,
nameCategorical: "0"
}
];
const varAnnotations = [];
const obsAnnotations = new Dataframe.Dataframe(
[3, 6],
[
["n0", "n1", "n2"],
["hi", "hi", "bye"],
[false, true, true],
new Float32Array([39.3, 39.3, 0]),
new Int32Array([99, 99, 99]),
[1, false, "0"]
],
null,
new Dataframe.KeyIndex([
"name",
"nameString",
"nameBoolean",
"nameFloat32",
"nameInt32",
"nameCategorical"
])
);
const varAnnotations = Dataframe.Dataframe.empty();
const summary = summarizeAnnotations(
schema,
@@ -178,7 +190,13 @@ describe("summarizeAnnotations", () => {
},
nameFloat32: {
categorical: false,
range: { min: 0, max: 39.3, nan: 0, ninf: 0, pinf: 0 }
range: {
min: 0,
max: float32Conversion(39.3),
nan: 0,
ninf: 0,
pinf: 0
}
},
nameInt32: {
categorical: false,
@@ -197,45 +215,32 @@ describe("summarizeAnnotations", () => {
});
test("non-finite numbers", () => {
const obsAnnotations = [
{
__index__: 0,
name: "n0",
nameString: "hi",
nameBoolean: false,
nameFloat32: 39.3,
nameInt32: 99,
nameCategorical: 1
},
{
__index__: 1,
name: "n1",
nameString: "hi",
nameBoolean: true,
nameFloat32: Number.NEGATIVE_INFINITY,
nameInt32: 99,
nameCategorical: false
},
{
__index__: 2,
name: "n2",
nameString: "bye",
nameBoolean: true,
nameFloat32: Number.NaN,
nameInt32: 99,
nameCategorical: "0"
},
{
__index__: 3,
name: "n2",
nameString: "bye",
nameBoolean: true,
nameFloat32: Number.POSITIVE_INFINITY,
nameInt32: 99,
nameCategorical: "0"
}
];
const varAnnotations = [];
const obsAnnotations = new Dataframe.Dataframe(
[4, 6],
[
["n0", "n1", "n2", "n2"],
["hi", "hi", "bye", "bye"],
[false, true, true, true],
new Float32Array([
39.3,
Number.NEGATIVE_INFINITY,
Number.NaN,
Number.POSITIVE_INFINITY
]),
new Int32Array([99, 99, 99, 99]),
[1, false, "0", "0"]
],
null,
new Dataframe.KeyIndex([
"name",
"nameString",
"nameBoolean",
"nameFloat32",
"nameInt32",
"nameCategorical"
])
);
const varAnnotations = Dataframe.Dataframe.empty();
const summary = summarizeAnnotations(
schema,
@@ -260,7 +265,13 @@ describe("summarizeAnnotations", () => {
},
nameFloat32: {
categorical: false,
range: { min: 39.3, max: 39.3, nan: 1, ninf: 1, pinf: 1 }
range: {
min: float32Conversion(39.3),
max: float32Conversion(39.3),
nan: 1,
ninf: 1,
pinf: 1
}
},
nameInt32: {
categorical: false,