6
$\begingroup$

Consider the dataset:

data = Dataset[{<|"A" -> 1|>, <| "A" -> 2|>}]

Define the function:

f[x_] := (Message[f::test]; x);

Note that f[1] returns 1 and f[2] returns 2, although messages are printed.

The following returns a Failure:

data[All, f[#["A"]] &]

(* Failure[f, Association["MessageTemplate" :> MessageName[f, "test"], 
   "MessageParameters" -> {}]]  *)

I have code that breaks because of this (messages from FindRoot were the culprit).

Update: As suggested by @Edmund in the comments, data[All, Quiet[f[#["A"]]]&] works. But Quiet[data[All, f[#["A"]] &]] does not.

$\endgroup$
  • $\begingroup$ The above code does not work in 10.3.1, 10.4.1, and 11.0 in Win 8.1 Pro. What version of Mathematica did it used to work in. $\endgroup$ – Edmund Sep 23 '16 at 0:58
  • $\begingroup$ Not sure. I thought it was working fine before. But the data did changed. So messages may not have been generated before $\endgroup$ – ecoxlinux Sep 23 '16 at 1:03
  • $\begingroup$ @Edmund Changed the question accordingly $\endgroup$ – ecoxlinux Sep 23 '16 at 1:05
  • 1
    $\begingroup$ Have you seen Quiet? $\endgroup$ – Edmund Sep 23 '16 at 1:06
  • $\begingroup$ Yes. But that seems like a nasty solution $\endgroup$ – ecoxlinux Sep 23 '16 at 1:13
7
$\begingroup$

The behaviour we see is due to the default FailureAction associated with dataset queries. The default action is to abort the entire computation if any message is issued:

data[All, If[#A == 1, #, Message[f::test]] &]

(* Failure[...] *)

Fortunately, we can override this behaviour. For example, we can instruct the query to take no special action in the face of messages:

data[All, If[#A == 1, #, f[#]] &, FailureAction -> None]

(*
   f: -- Message text not found --
   { <| "A" -> 1|>, <| "B" -> 1 |> }
 *)

Messages are issued as normal and the final dataset is produced. Incidentally, this option is incredibly useful when debugging complex dataset queries.

We can also drop each individual result if its computation issues a message:

data[All, If[#A == 1, #, f[#]] &, FailureAction -> "Drop"]

(* { <| "A" -> 1 |> } *)

... or encapsulate individual failed results within Failure objects:

data[All, If[#A == 1, #, f[#]] &, FailureAction -> "Encapsulate"]

(* <| "A" -> 1 |>, Failure[...] } *)

... or replace failed results with a Missing expression:

data[All, If[#A == 1, #, f[#]] &, FailureAction -> "Replace"]

(* {<|"A" -> 1|>, Missing["Failed"]} *)

We can enhance most of the action types with a user function which is applied to Failure objects (the function g in this example):

data[All, If[#A == 1, #, f[#]] &, FailureAction -> {"Replace", g}]

(* { <| "A" -> 1 |>, g[Failure[...]] } *)

Finally, we can explicitly specify the "Abort" action which is the default:

data[All, If[#A == 1, #, f[#]] &, FailureAction -> "Abort"]

(* Failure[...] *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.