Skip to content

Commit

Permalink
[Platform] Add/fix column sorting (#595)
Browse files Browse the repository at this point in the history
* nullish comparator and make betas sortable

* posterior probs and variant sorting

* other sorting fixes

* optional chaining
  • Loading branch information
gjmcn authored Dec 6, 2024
1 parent 4035fcc commit 230bcf0
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 64 deletions.
2 changes: 1 addition & 1 deletion packages/sections/src/credibleSet/GWASColoc/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const columns = [
{
id: "otherStudyLocus.variant.id",
label: "Lead Variant",
comparator: variantComparator,
comparator: variantComparator(d => d?.otherStudyLocus?.variant),
sortable: true,
filterValue: ({ otherStudyLocus }) => {
const v = otherStudyLocus?.variant;
Expand Down
2 changes: 1 addition & 1 deletion packages/sections/src/credibleSet/MolQTLColoc/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const columns = [
{
id: "otherStudyLocus.variant.id",
label: "Lead Variant",
comparator: variantComparator,
comparator: variantComparator(d => d?.otherStudyLocus?.variant),
sortable: true,
filterValue: ({ otherStudyLocus }) => {
const v = otherStudyLocus?.variant;
Expand Down
9 changes: 5 additions & 4 deletions packages/sections/src/credibleSet/Variants/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function getColumns({ leadVariantId, leadReferenceAllele, leadAlternateAllele }:
{
id: "variant.id",
label: "Variant",
comparator: variantComparator,
comparator: variantComparator(d => d?.variant),
sortable: true,
filterValue: ({ variant: v }) =>
`${v?.chromosome}_${v?.position}_${v?.referenceAllele}_${v?.alternateAllele}`,
Expand Down Expand Up @@ -78,6 +78,7 @@ function getColumns({ leadVariantId, leadReferenceAllele, leadAlternateAllele }:
id: "beta",
label: "Beta",
filterValue: false,
sortable: true,
tooltip: "Beta with respect to the ALT allele",
renderCell: ({ beta }) => {
if (typeof beta !== "number") return naLabel;
Expand Down Expand Up @@ -148,9 +149,9 @@ function getColumns({ leadVariantId, leadReferenceAllele, leadAlternateAllele }:
const mostSevereConsequence = variant?.mostSevereConsequence
if (!mostSevereConsequence) return naLabel;
const displayElement = (
<Link external to={identifiersOrgLink("SO", mostSevereConsequence.id.slice(3))}>
{formatVariantConsequenceLabel(mostSevereConsequence.label)}
</Link>
<Link external to={identifiersOrgLink("SO", mostSevereConsequence.id.slice(3))}>
{formatVariantConsequenceLabel(mostSevereConsequence.label)}
</Link>
);
return displayElement;
},
Expand Down
25 changes: 19 additions & 6 deletions packages/sections/src/evidence/GWASCredibleSets/Body.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import {
OtScoreLinearBar,
Tooltip,
Navigate,
DisplayVariantId,
} from "ui";

import { variantComparator } from "../../utils/comparators";
import { naLabel, sectionsBaseSizeQuery, credsetConfidenceMap } from "../../constants";
import { definition } from ".";
import Description from "./Description";
Expand All @@ -30,11 +31,22 @@ function getColumns(targetSymbol) {
{
id: "variantId",
label: "Lead Variant",
sortable: true,
comparator: variantComparator(d => d?.credibleSet?.variant),
renderCell: ({ credibleSet }) => {
const variantId = credibleSet?.variant?.id;
if (variantId) return <Link to={`/variant/${variantId}`}>{variantId}</Link>;
return naLabel;
const v = credibleSet?.variant;
if (!v) return naLabel;
return <Link to={`/variant/${v.id}`}>
<DisplayVariantId
variantId={v.id}
referenceAllele={v.referenceAllele}
alternateAllele={v.alternateAllele}
expand={false}
/>
</Link>
},
filterValue: ({ variant: v }) =>
`${v?.chromosome}_${v?.position}_${v?.referenceAllele}_${v?.alternateAllele}`,
},
{
id: "trait",
Expand Down Expand Up @@ -91,11 +103,12 @@ function getColumns(targetSymbol) {
},
},
{
id: "betaConfidenceInterval",
id: "credibleSet.beta",
label: "Beta (CI 95%)",
numeric: true,
sortable: true,
renderCell: ({ credibleSet }) => {
return credibleSet?.beta ? `${parseFloat(credibleSet?.beta.toFixed(3))}` : naLabel;
return credibleSet?.beta ? credibleSet.beta.toFixed(3) : naLabel;
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ query GwasCredibleSetsQuery($ensemblId: String!, $efoId: String!, $size: Int!) {
}
variant {
id
chromosome
position
referenceAllele
alternateAllele
}
pValueMantissa
pValueExponent
Expand Down
31 changes: 22 additions & 9 deletions packages/sections/src/evidence/UniProtVariants/Body.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { useQuery } from "@apollo/client";
import { Typography } from "@mui/material";
import { Link, SectionItem, Tooltip, PublicationsDrawer, LabelChip, OtTable } from "ui";

import {
Link,
SectionItem,
Tooltip,
PublicationsDrawer,
LabelChip,
OtTable,
DisplayVariantId,
} from "ui";
import { definition } from ".";

import Description from "./Description";
import { epmcUrl } from "../../utils/urls";
import { dataTypesMap } from "../../dataTypes";
import { identifiersOrgLink } from "../../utils/global";
import { variantComparator } from "../../utils/comparators";
import { nullishComparator, variantComparator } from "../../utils/comparators";
import {
defaultRowsPerPageOptions,
variantConsequenceSource,
Expand Down Expand Up @@ -52,13 +58,20 @@ function getColumns(label) {
{
id: "variantId",
label: "Variant",
comparator: variantComparator,
sortable: true,
comparator: nullishComparator(variantComparator(), d => d?.variant),
filterValue: ({ variant: v }) =>
`${v?.chromosome}_${v?.position}_${v?.referenceAllele}_${v?.alternateAllele}`,
renderCell: ({ variant }) => {
if (variant) return <Link to={`/variant/${variant.id}`}>{variant.id}</Link>;
return naLabel;
renderCell: ({ variant: v }) => {
if (!v) return naLabel;
return <Link to={`/variant/${v.id}`}>
<DisplayVariantId
variantId={v.id}
referenceAllele={v.referenceAllele}
alternateAllele={v.alternateAllele}
expand={false}
/>
</Link>
},
},
{
Expand All @@ -84,7 +97,7 @@ function getColumns(label) {
}
return naLabel;
}
},
},
{
id: "variantConsequence",
label: "Variant Consequence",
Expand Down
12 changes: 8 additions & 4 deletions packages/sections/src/study/GWASCredibleSets/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { naLabel, credsetConfidenceMap, initialResponse, table5HChunkSize } from
import { definition } from ".";
import Description from "./Description";
import GWAS_CREDIBLE_SETS_QUERY from "./GWASCredibleSetsQuery.gql";
import { mantissaExponentComparator, variantComparator } from "../../utils/comparators";
import { mantissaExponentComparator, nullishComparator, variantComparator } from "../../utils/comparators";
import ManhattanPlot from "./ManhattanPlot";
import { useEffect, useState } from "react";
import { responseType } from "ui/src/types/response";
Expand All @@ -28,7 +28,7 @@ const columns = [
{
id: "leadVariant",
label: "Lead variant",
comparator: variantComparator,
comparator: variantComparator(d => d?.variant),
sortable: true,
filterValue: ({ variant: v }) =>
`${v?.chromosome}_${v?.position}_${v?.referenceAllele}_${v?.alternateAllele}`,
Expand Down Expand Up @@ -73,6 +73,7 @@ const columns = [
id: "beta",
label: "Beta",
filterValue: false,
sortable: true,
tooltip: "Beta with respect to the ALT allele",
renderCell: ({ beta }) => {
if (typeof beta !== "number") return naLabel;
Expand Down Expand Up @@ -114,8 +115,11 @@ const columns = [
{
id: "l2gScore",
label: "L2G score",
comparator: (rowA, rowB) =>
rowA?.l2GPredictions?.rows[0]?.score - rowB?.l2GPredictions?.rows[0]?.score,
comparator: nullishComparator(
(a, b) => a - b,
row => row?.l2GPredictions?.rows[0]?.score,
false,
),
sortable: true,
tooltip:
"Machine learning prediction linking a gene to a credible set using all features. Score range [0,1].",
Expand Down
3 changes: 2 additions & 1 deletion packages/sections/src/study/QTLCredibleSets/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const columns = [
{
id: "leadVariant",
label: "Lead variant",
comparator: variantComparator,
comparator: variantComparator(d => d?.variant),
sortable: true,
filterValue: ({ variant: v }) =>
`${v?.chromosome}_${v?.position}_${v?.referenceAllele}_${v?.alternateAllele}`,
Expand Down Expand Up @@ -68,6 +68,7 @@ const columns = [
{
id: "beta",
label: "Beta",
sortable: true,
filterValue: false,
tooltip: "Beta with respect to the ALT allele",
renderCell: ({ beta }) => {
Expand Down
78 changes: 51 additions & 27 deletions packages/sections/src/utils/comparators.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

/*
Example usage:
const comparatorDiseaseName = generateComparatorFromAccessor(d => d.disease.name);
Expand All @@ -10,6 +11,23 @@ export const generateComparatorFromAccessor = accessor => (a, b) => {
return -1;
};

/*
Return comparator that sorts nullish values to end
*/
export const nullishComparator =
(comparator, accessor = x => x, nullishIsMax = true) => {
return (a, b) => {
const aVal = accessor(a);
const bVal = accessor(b);
if (aVal == null) {
if (bVal == null) return 0;
return nullishIsMax ? 1 : -1;
}
if (bVal === null) return nullishIsMax ? -1 : 1;
return comparator(aVal, bVal);
};
};

/*
Compares a breakpoint against a breakpoint helper.
*/
Expand Down Expand Up @@ -47,37 +65,43 @@ chromosomeRank.set('X', 23);
chromosomeRank.set('Y', 24);

type VariantType = {
variant: {
chromosome: string;
position: number;
referenceAllele: string;
alternateAllele: string;
}
chromosome: string;
position: number;
referenceAllele: string;
alternateAllele: string;
};

export function variantComparator(
{ variant: v1 }: VariantType,
{ variant: v2 }: VariantType
) {

if (!v1 || !v2) return 0;

const chromosomeDiff =
chromosomeRank.get(v1.chromosome) - chromosomeRank.get(v2.chromosome);
if (chromosomeDiff !== 0) return chromosomeDiff;

const positionDiff = v1.position - v2.position;
if (positionDiff !== 0) return positionDiff

if (v1.referenceAllele < v2.referenceAllele) return -1;
else if (v1.referenceAllele > v2.referenceAllele) return 1;
else if (v1.alternateAllele < v2.alternateAllele) return -1;
else if (v1.alternateAllele > v2.alternateAllele) return 1;

return 0;
export function variantComparator(accessor: (arg: any) => VariantType = d => d) {

return function (obj1: any, obj2: any) {
const v1 = accessor(obj1);
const v2 = accessor(obj2);

if (!v1 || !v2) return 0;

const chromosomeDiff =
chromosomeRank.get(v1.chromosome) - chromosomeRank.get(v2.chromosome);
if (chromosomeDiff !== 0) return chromosomeDiff;

const positionDiff = v1.position - v2.position;
if (positionDiff !== 0) return positionDiff

if (v1.referenceAllele < v2.referenceAllele) return -1;
else if (v1.referenceAllele > v2.referenceAllele) return 1;
else if (v1.alternateAllele < v2.alternateAllele) return -1;
else if (v1.alternateAllele > v2.alternateAllele) return 1;

return 0;
}

}

export function mantissaExponentComparator(m1, e1, m2, e2) {
export function mantissaExponentComparator(m1, e1, m2, e2, nullishIsMax = true) {
if (m1 == null || e1 == null) {
if (m2 == null || e2 == null) return 0;
return nullishIsMax ? 1 : -1;
}
if (m2 == null || e2 == null) return nullishIsMax ? -1 : 1;
if (e1 === e2) return m1 - m2;
return e1 - e2;
}
18 changes: 12 additions & 6 deletions packages/sections/src/variant/GWASCredibleSets/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { definition } from ".";
import Description from "./Description";
import GWAS_CREDIBLE_SETS_QUERY from "./GWASCredibleSetsQuery.gql";
import { Fragment } from "react/jsx-runtime";
import { mantissaExponentComparator, variantComparator } from "../../utils/comparators";
import { mantissaExponentComparator, variantComparator, nullishComparator } from "../../utils/comparators";
import PheWasPlot from "./PheWasPlot";
import { useEffect, useState } from "react";
import { responseType } from "ui/src/types/response";
Expand All @@ -37,7 +37,7 @@ function getColumns({ id, referenceAllele, alternateAllele }: getColumnsType) {
{
id: "leadVariant",
label: "Lead variant",
comparator: variantComparator,
comparator: variantComparator(d => d?.variant),
sortable: true,
filterValue: ({ variant: v }) =>
`${v?.chromosome}_${v?.position}_${v?.referenceAllele}_${v?.alternateAllele}`,
Expand Down Expand Up @@ -128,6 +128,7 @@ function getColumns({ id, referenceAllele, alternateAllele }: getColumnsType) {
label: "Beta",
filterValue: false,
tooltip: "Beta with respect to the ALT allele",
sortable: true,
renderCell: ({ beta }) => {
if (typeof beta !== "number") return naLabel;
return beta.toPrecision(3);
Expand All @@ -149,8 +150,10 @@ function getColumns({ id, referenceAllele, alternateAllele }: getColumnsType) {
) is causal.
</>
),
comparator: (rowA, rowB) =>
rowA.locus.rows[0].posteriorProbability - rowB.locus.rows[0].posteriorProbability,
comparator: (a, b) => {
return a?.locus?.rows?.[0]?.posteriorProbability -
b?.locus?.rows?.[0]?.posteriorProbability;
},
sortable: true,
renderCell: ({ locus }) =>
locus.count > 0 ? locus?.rows[0]?.posteriorProbability.toFixed(3) : naLabel,
Expand Down Expand Up @@ -192,8 +195,11 @@ function getColumns({ id, referenceAllele, alternateAllele }: getColumnsType) {
{
id: "l2gScore",
label: "L2G score",
comparator: (rowA, rowB) =>
rowA?.l2GPredictions?.rows[0]?.score - rowB?.l2GPredictions?.rows[0]?.score,
comparator: nullishComparator(
(a, b) => a - b,
row => row?.l2GPredictions?.rows[0]?.score,
false,
),
sortable: true,
tooltip:
"Machine learning prediction linking a gene to a credible set using all features. Score range [0,1].",
Expand Down
Loading

0 comments on commit 230bcf0

Please sign in to comment.