I had forgot about this question, or the answer linked by @Leonid, or @jVincent's etc, and last week I was under the same "need".
I'll just post what I used since it's no extra work, in case it still helps someone.
Speed wasn't a concern, so I have no clue how much time this wastes
LabeledMatrix[cs_, mat_][cols : {__String}, funQ_] :=
LabeledMatrix[cs, mat][cols, funQ, cols];
Normal[LabeledMatrix[_, mat_, ___]] ^:= mat
(lm : LabeledMatrix[cs_, mat_?MatrixQ])[cols : {__String}, funQ_, showCols : {___String}] :=
Extract[mat[[All, label2Position[lm, showCols]]],
Position[LabeledMatrix[cs, mat][cols], {i___} /; funQ[i], {1}]];
LabeledMatrix[cs_, mat_?MatrixQ][cols : {__String}, All] :=
LabeledMatrix[cs, mat][cols];
(lm : LabeledMatrix[cs_, mat_?MatrixQ])[cols : {__String}] :=
mat[[All, label2Position[lm, cols]]];
SetAttributes[label2Position, Listable];
label2Position[LabeledMatrix[cols_List, ___], lab_] :=
First@Flatten@Position[cols, lab, {1}, 1];
There's basically no error checking, formatting rules, etc.
Usage
LabeledMatrix
is a wrapper. It takes, as a first argument, the names of the columns, and as a second, the data matrix.
lm = LabeledMatrix[
{"ID", "Person", "Age"},
{{4, "Peter", 23}, {5, "Mary", 33}, {55, "John", 23}}];
Say you want the "Person" and "Age", column
lm[{"Person", "Age"}]
(* {{"Peter", 23}, {"Mary", 33}, {"John", 23}} *)
The first argument, (unless you use the 3 argument form), is a list of the columns you want as output.
If you give a second argument, then that second argument is a predicate function to filter rows. The arguments taken by that function are those supplied in the first argument. Example
lm[{"Age", "ID"}, #2 > #1 &]
(* {{23, 55}} *)
If you supply a third argument, it's the list of columns returned. The first argument still works as the input to the predicate. So, say you want the IDs of the people aged under 30
lm[{"Age"}, # < 30 &, {"ID"}]
(* {{4}, {55}} *)
A second argument of All
is the same as nothing. Normal
gives the data matrix. First
, or some other convenience function you want to create, the names of the columns.
Extract[theTable, Position[theTable, {_, "blue", x_ /; x > 10, _}]]
works, right? $\endgroup$DatabaseLink
. $\endgroup$