# Labeling elements of a table

I have a table of the form(the table is very long, i put an example):

 tab1={{{1,10,30},{1,20,54},{1,30,65}},{{2,10,35},{2,20,65},{2,30,70}}}


How can I give index to elements of this table? I would like to have such a rule:

 tab1[x][y][z]


so that I can operate on its elements. For example, I would like to obtain,for every x:

 sum[x]=30+54+65  (*sum of z given x=1*)


And for every y:

 sum[y]=30+35    (*sum of z given y=10*)

• Total with level specification? Commented Jun 15, 2020 at 9:02
• I am not able to understand why sum[x]=30+54+65 is sum of z given x=1? How did it know to sum only the third elements in the first list, and not say sum the second elements of the first list? And also sum[y]=30+35 is sum of z given y=10 how? Please try to explain more clearly how these were generated. If there are implicit assumption, then make them explicit. Any way, as was mentioned above, better to just use Total with the proper Part specifications. No need for all this gymnastics just to access parts of lists. Mathematica has good support to access any Part of lists. ? [[ ]] Commented Jun 15, 2020 at 9:17
• These are given data, in a triplet form whose first, second and third elements are respectively x,y and z. All I want to do is ,for a given x, to sum z's for different y's and, for a given y, sum z's for different x's. Commented Jun 15, 2020 at 9:23

You might consider Dataset for the kind of slicing/dicing you wish to perform:

ds = Dataset[Join @@ MapIndexed[
AssociationThread[{"class", "group", "x", "y", "z"}, Flatten[{#2, #}]] &, tab1, {2}]]


ds[GroupBy["x"], All, {"y", "z"}]


ds[GroupBy["y"] /* Map[Total], Select[#"x" == 1 &], {"z"}]


We can define a function that takes a predicate, a grouping key, a list of target keys and a function to be applied to the target keys:

ClearAll[foo]
foo[selector_, groupbykey_, keys_List, func_] :=
ds[GroupBy[groupbykey] /* Map[func], Select[selector], keys]


Examples:

foo[#x == 1 &, "y", {"z"}, Total]


foo[True &, "y", {"z"}, List]


foo[True &, "y", {"z"}, Total]


foo[#z >= 35 &, "x", {"y", "group"}, Mean]


foo[#z >= 35 &, "x", {"y", "group"}, Identity]


foo[#z >= 35 &, "x", {"y", "group"}, bar]


These are given data, in a triplet form whose first, second and third elements are respectively x,y and z. All I want to do is ,for a given x, to sum z's for different y's and, for a given y, sum z's for different x's.

In that case, why do you care about having them as list of list of lists? You could Flatten them at 1 and just do

sum[label_, value_, list_List] := Module[{r},

(*assumes list has the form {{x,y,z},{x,y,z},...,{x,y,z}}*)

r = Which[label == "x",
Cases[list, {value, _, _}],
label == "y",
Cases[list, {_, value, _}],
label == "z",
Cases[list, {_, _, value}]
];
Total[r[[All, 3]]]
];


Call it as

tab1 = {{{1, 10, 30}, {1, 20, 54}, {1, 30, 65}},
{{2, 10, 35}, {2, 20, 65}, {2, 30, 70}}
};
sum["x", 1, Flatten[tab1, 1]]
(* 149 *)

sum["y", 10, Flatten[tab1, 1]]
(* 65 *)

sum["y", 30, Flatten[tab1, 1]]
(*135*)


etc.. The function above is just to make it easier. Otherwise, you could just do

Total[Cases[Flatten[tab1, 1], {1, _, _}][[All, 3]]]
(* 149 *)

Total[Cases[Flatten[tab1, 1], {_, 10, _}][[All, 3]]]
(*65*)


etc...