Missing values are a pain mathematically and computationally in general not just in WL, but I think this problem is more related to Dataset handling of warnings:

Select Works w/ a warning on Association lists::

{<|"a" -> "hey"|>, <| "a" -> Missing[]|>} // 
 Select[StringMatchQ[#a, "hey"] &] 
StringMatchQ::strse: "String or list of strings expected at position 1 in \!\(StringMatchQ[Missing[], \"hey\"]\). "
{<|"a" -> "hey"|>}

Fails as a Query:

Dataset[{<|"a" -> "hey"|>, <| "a" -> Missing[]|>} ] [
 Select[StringMatchQ[#a, "hey"] &]]


The Dataset docs only mentions Missing 4x and not in this context. Is there a workaround that lets it ignore such warnings?

  • $\begingroup$ One workaround for above is pre-replace missing values by empty string or similar, Query[All, {"a" -> Replace[Missing[] -> ""]}], violates the spirit of Missing $\endgroup$ May 8, 2015 at 18:39
  • $\begingroup$ Select[StringMatchQ[ToString[#a], "hey"] &]? $\endgroup$
    – chuy
    May 8, 2015 at 19:26
  • $\begingroup$ Why not just keep it Quiet. Dataset[{<|"a" -> "hey"|>, <|"a" -> Missing[]|>}][ Select[Function[Quiet[StringMatchQ[#a, "hey"]]]]] $\endgroup$
    – Hans
    May 8, 2015 at 19:39
  • $\begingroup$ As If[] anyone is listening: Dataset[{<|"a" -> "hey"|>, <|"a" -> Missing[]|>, <|"a" -> 23|>}][ Select[Function[If[Head[#a] == String , StringMatchQ[#a, "hey"]]]]] $\endgroup$
    – Hans
    May 8, 2015 at 20:13

1 Answer 1


In the example you give, your Query function asks if the value at element "a" is a string match for "hey". This generates the message because the value for a is not a string in the second row of your dataset.

For this particular case, one solution would be to require an exact match:

data = Dataset[{<|"a" -> "hey"|>, <|"a" -> Missing[]|>}];
Normal@data[Select[#a === "hey"&]]

This works just fine in the example, but if you need to use an actual string match, e.g. of a string pattern, rather than a match using SameQ (===), I don't see a method that's particularly more elegant than changing your select function:

data[Select[StringQ[#a] && StringMatchQ[#a, "hey"] &]]

That said, as chuy noted in your question's comments, you can also force the #a to be a string:

data[Select[StringMatchQ[ToString[#a], "hey"] &]]

Or, as alancalvitti noted, you can pre-select the valid rows:

data[All, {"a" -> Replace[_Missing -> ""]}][Select[#a == "hey" &]]

Or, as Hans points out, you can use a Quiet[] form:

data[Select[Quiet[StringMatchQ[#a "hey"]] &]]

All of these produce correct results.

  • $\begingroup$ This problem shows up generically w/ Missing, it's inconvenient to modify the logic just to handle those. $\endgroup$ May 8, 2015 at 22:41
  • $\begingroup$ In that case you might consider something like this: Block[{Missing}, Missing[___]:=""; data[Select[#a == "hey"&]]]; The block + Missing[___] := ""; will redefine all of the instances of Missing[...] (with any number of arguments) in your dataset while it evaluates it. Note that it will affect all missing entries, not just the ones you intend to be strings. $\endgroup$
    – nben
    May 8, 2015 at 22:48
  • $\begingroup$ Thanks butr even wrapping Block is a pain - the behavior should be specified globally. Also, ran into an edge case where data // Select[Quiet...] works but data[Select[Quiet...]]fails. $\endgroup$ May 11, 2015 at 18:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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