force categorical treatment of user annotations (#1663)

This commit is contained in:
Bruce Martin
2020-07-22 17:02:19 -07:00
committed by GitHub
parent 03bad04436
commit 83d572cde2
5 changed files with 39 additions and 20 deletions
+19 -10
View File
@@ -34,7 +34,8 @@ export const annotationCreateCategoryAction = (
throw new Error("name collision on annotation category create");
let initialValue;
let categories;
let newSchema;
let ctor;
if (categoryToDuplicate) {
/* if we are duplicating a category, retrieve it */
const catDupSchema = schema.annotations.obsByName[categoryToDuplicate];
@@ -47,25 +48,33 @@ export const annotationCreateCategoryAction = (
.fetch("obs", categoryToDuplicate);
const col = catToDupDf.col(categoryToDuplicate);
initialValue = col.asArray();
({ categories } = col.summarize());
const { categories } = col.summarizeCategorical();
// all user-created annotations must have the unassigned category
if (!categories.includes(globals.unassignedCategoryLabel)) {
categories.push(globals.unassignedCategoryLabel);
}
ctor = initialValue.constructor;
newSchema = {
...catDupSchema,
name: newCategoryName,
categories,
writable: true,
};
} else {
/* else assign to the standard default value */
initialValue = globals.unassignedCategoryLabel;
categories = [globals.unassignedCategoryLabel];
ctor = Array;
newSchema = {
name: newCategoryName,
type: "categorical",
categories: [globals.unassignedCategoryLabel],
writable: true,
};
}
const obsCrossfilter = prevObsCrossfilter.addObsColumn(
{
name: newCategoryName,
type: "categorical",
categories,
writable: true,
},
Array,
newSchema,
ctor,
initialValue
);
+6 -8
View File
@@ -90,10 +90,10 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
If an array, it must be of same size as nObs and same type as Ctor
*/
colSchema.writable = true;
const col = colSchema.name;
const colName = colSchema.name;
if (
_getColumnSchema(this.schema, "obs", col) ||
this._cache.obs.hasCol(col)
_getColumnSchema(this.schema, "obs", colName) ||
this._cache.obs.hasCol(colName)
) {
throw new Error("column already exists");
}
@@ -109,11 +109,9 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
} else {
data = new Ctor(this.nObs).fill(value);
}
o._cache.obs = this._cache.obs.withCol(col, data);
o.schema = addObsAnnoColumn(this.schema, col, {
...colSchema,
writable: true,
});
o._cache.obs = this._cache.obs.withCol(colName, data);
_normalizeCategoricalSchema(colSchema, o._cache.obs.col(colName));
o.schema = addObsAnnoColumn(this.schema, colName, colSchema);
return o;
}
+7 -1
View File
@@ -66,7 +66,12 @@ export function _isContinuousType(schema) {
export function _normalizeCategoricalSchema(colSchema, col) {
const { type, writable } = colSchema;
if (type === "string" || type === "boolean" || type === "categorical") {
if (
type === "string" ||
type === "boolean" ||
type === "categorical" ||
writable
) {
const categorySet = new Set(
col.summarizeCategorical().categories.concat(colSchema.categories ?? [])
);
@@ -79,4 +84,5 @@ export function _normalizeCategoricalSchema(colSchema, col) {
if (colSchema.categories) {
colSchema.categories = catLabelSort(writable, colSchema.categories);
}
return colSchema;
}
@@ -16,6 +16,7 @@ class Continuous extends React.PureComponent {
const allContinuousNames = schema.annotations.obs.columns
.filter((col) => col.type === "int32" || col.type === "float32")
.filter((col) => col.name !== obsIndex)
.filter((col) => !col.writable) // skip user annotations - they will be treated as categorical
.map((col) => col.name);
return (
@@ -64,7 +64,12 @@ function topNCategories(colSchema, summary, N) {
export function isSelectableCategoryName(schema, name) {
const { index } = schema.annotations.obs;
return name && name !== index && isCategoricalAnnotation(schema, name);
const colSchema = schema.annotations.obsByName[name];
return (
name &&
name !== index &&
(isCategoricalAnnotation(schema, name) || colSchema.writable)
);
}
export function selectableCategoryNames(schema, names) {