1
$\begingroup$

I learned how to query Dataset for rows that contain a certain value, but now I need to query for a long series of And in chain on the value of several columns. So in short I am trying to identify the row where x={x1, ..., xn} takes a certain value.

For a Dataset like this

  ds = Dataset[{Association[{"x1" -> myX, "x2" -> myX, "x3" -> myX, 
  "x4" -> myX, "y" -> myY}], 
Association[{"x1" -> myotherX, "x2" -> myotherX, "x3" -> myX, 
  "x4" -> myX, "y" -> myotherY}]}];

I can do

   ds[Select[(#x1 == myotherX && #x2 == myotherX && #x3 == myX && #x4 == 
  myX) &], "y"]

but the expression is long to type and less and less convenient as from 2 argument I go to a larger numbers.

Ideally I wanted to able to call something like

  ReadRow[ds,<|"x1"->myX,"x2"->myX,"x3"->myX,"x4"->myX|>,"y"]

Any idea how to do this? something like this should be a standard way to deal with Dataset.


My best result so far is to "translate" the Association into a check for the value I am looking for and put all the entered keys of the association

  RuleToEquality[a_, b_] := Slot[a] == b
  MgPyResults[
        Select[(KeyValueMap[RuleToEquality, <|x1 -> myX|>][[1]]) &], "y"]

This, however, does not match the entries, despite the

InputForm[
     Tr[KeyValueMap[RuleToEquality, <|x1 -> myX, x2 -> myX|>], And]]

gives the correct

 Slot[x1] == myX && Slot[x2] == myX
$\endgroup$
  • $\begingroup$ Your verbal description and you code examples don't seem consistent to me. Further, a data set with only one row doesn't make for a good example. I am voting to close this question as unclear. $\endgroup$ – m_goldberg Aug 29 '15 at 13:11
  • $\begingroup$ One row is more than enough to retrieve one row. Why should I put on the code more entries than needed? anyways, I am editing the question, maybe is only my point of view. $\endgroup$ – Rho Phi Aug 29 '15 at 13:19
  • $\begingroup$ @RobertoFranceschini, "Why should I put on the code more entries than needed?" non-matching entries are typically needed to test potential false positives. $\endgroup$ – alancalvitti Sep 3 '15 at 21:57
  • $\begingroup$ In your ReadRow[ds,<|x1->myX,x2->myX,x3->myX,x4->myX|>,"y"] the Keys in your example are strings so x1... should be wrapped in quotes. $\endgroup$ – alancalvitti Sep 3 '15 at 22:00
  • $\begingroup$ correct(ed), thanks for "compiling" my question :) $\endgroup$ – Rho Phi Sep 14 '15 at 13:48
3
$\begingroup$

If you have your $\{column, value\}$ pairs in a list

findList = {{"x1", myX}, {"x2", myX}, {"x3", myX}, {"x4", myX}};

then you can build the Select criteria function from it.

selectCriteria[find_List] :=
 And @@ Function[{item}, #[item[[1]]] == item[[2]]] /@ find &

selectCriteria builds up the Equal pairs and chains them with And. It returns a function that can be used with Select.

ds[Select[selectCriteria[findList]], "y"]
(* {myY} *)

If your pairs are in an Association then convert it to a List before calling selectCriteria.

findAssc = <|"x1" -> myX, "x2" -> myX, "x3" -> myX, "x4" -> myX|>;

ds[Select[selectCriteria[List @@@ Normal@findAssc]], "y"]
(* {myY} *)

Hope this helps.

$\endgroup$
2
$\begingroup$

Possibly this will be of use to you:

ds = Dataset[{
     <|"x1" -> myX, "x2" -> myX, "x3" -> myX, "x4" -> myX, "y" -> myY|>,
     <| "x1" -> myotherX, "x2" -> myotherX, "x3" -> myX, "x4" -> myX, "y" -> myotherY|>
   }];

sel = <|"x1" -> myX, "x2" -> myX, "x3" -> myX, "x4" -> myX|>;

sel2 = <|"x1" -> myotherX, "x2" -> myotherX, "x3" -> myX, "x4" -> myX|>;

pull[sel_] := Select[sel == KeyTake[#, Keys@sel] &];

ds[pull @ sel, "y"]
ds[pull @ sel2, "y"]
{myY}

{myotherY}
$\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.