Skip to main content

list manipulation - Composition with Transpose failure with Dataset


Is the failure of the 2nd Transpose here a known bug?


Dataset[{{0, 10}, {2, 11}, {3, 12}}][
Transpose /* Map[MinMax] /* Transpose] // Normal



Failure[Transpose, {"MessageTemplate" :> Transpose::nmtx, 
"MessageParameters" -> {{__}, Transpose}}]

Similarly for


Dataset[{{0, 10}, {2, 11}, {3, 12}}][
Query[Transpose /* Map[MinMax]] /* Transpose]

For both of these, without the Normal, the error msg is: "The first two levels of {__} cannot be transposed".


Yet the seeming equivalent query, albeit with an intermediate Dataset, works:



Dataset[{{0, 10}, {2, 11}, {3, 12}}][Transpose /* Map[MinMax] ][
Transpose]// Normal

And without Dataset, this works also:


{{0, 10}, {2, 11}, {3, 12}} // Transpose // Map[MinMax] // Transpose


{{0, 10}, {3, 12}}




Answer




The problem is due to two factors:



  1. The type system cannot infer the data type that results from a call to MinMax.

  2. A type-checked application of the Transpose query operator will fail when applied to an argument with an unknown type (i.e. from MinMax).


I think that point #1 could be considered a bug, although the fact of the matter is that a great many operators are not (yet) known to the type system. Given these omissions, it might be reasonable to expect the Transpose operator to be more forgiving.


Analysis (current as of version 11.0.1)


When an operation succeeds outside of a Dataset but fails within, the cause is usually a type-inferencing failure. That is indeed the case here.


traceTypes will reveal the failure:


traceTypes[Dataset[{{0, 10}, {2, 11}, {3, 12}}]][Transpose /* Map[MinMax] /* Transpose]


traceTypes screenshot


We can see that the type machinery cannot infer the resultant type of applying MinMax to a list of integers:


Needs["TypeSystem`"]
TypeApply[MinMax, {Vector[Atom[Integer], 3]}]
(* UnknownType *)

Furthermore, a type-checked application of AssociationTranspose (the query-form of Transpose) will not accept a vector of unknown type:


Needs["GeneralUtilities`"]
TypeApply[AssociationTranspose, {Vector[UnknownType, 2]}]

(* FailureType[{Transpose, "nmtx"}, <|"Arguments" -> {__}|>] *)

This last failure is the source of the message we see.


Work-around


As noted in the question, a work-around is to perform the final Transpose in a second query:


Dataset[{{0, 10}, {2, 11}, {3, 12}}][Transpose /* Map[MinMax]][Transpose]

double-query dataset screenshot


When the final query result is wrapped back into a dataset, type deduction takes place which is more reliable than type inferencing. By splitting our query in two, we allow such type deduction to take place so that the final Transpose operator can be applied to a known type:


Needs["Dataset`"]

Dataset[{{0, 10}, {2, 11}, {3, 12}}][Transpose /* Map[MinMax]] // GetType
(* Vector[Vector[Atom[Integer], 2], 2] *)

TypeApply[AssociationTranspose, {Vector[Vector[Atom[Integer], 2], 2]}]
(* Vector[Vector[Atom[Integer], 2], 2] *)

Comments