1
$\begingroup$

I have a list structured like

list1 = {{"header1","header2","header3"},
        {0,1,2}};

and I'm using a custom function to find the number of the column with a specific header name, and then extract the data for this column:

header = "header1"
data = Map[Part[#,All,whatColumn[header]] &,list1]; 

Now let's say I would like to extract data for both column "header1" and "header2", I would need to Map the above code line on the following list:

list2 = {"header1", "header2"};

but how do I organize my placeholders # ?

Something like this doesn't seem to work:

data = Map[Map[Part[#2,All,whatColumn[#1]] &,list1] &, list2]; 
$\endgroup$
1
  • 1
    $\begingroup$ But extracting one column doesn't need Map. Part[list1, All, 2] extracts 2nd column, and Map[Part[list1, All, #] &, {1, 3}] both 1st and 3rd. $\endgroup$
    – BoLe
    Mar 26, 2013 at 13:50

3 Answers 3

2
$\begingroup$

Does this provide you a bit more flexibility in getting what you want?

whatColumn[headers_List] := Flatten[Position[list1[[1]], #] & /@ headers]
list1 = {{"header1", "header2", "header3"}, {0, 1, 2}};
list2 = {"header1", "header3"};
Part[list1, All, #] & /@ whatColumn[list2]

{{"header1", 0}, {"header3", 2}}

The whatColumn[] function would seem to fit into your original frame work extending BoLe's idea.

Note that this works seamlessly with a single header or multiple ones. You just need to make list2 a List, even if it has only one element.

$\endgroup$
1
$\begingroup$

I would suggest another way of structuring your data, if you are still early in the development stage:

data = {"a" -> 1, "b" -> 2, "c" -> 3};

"a" /. data

(* 1 *)

{"a", "b"} /. data

(* {1, 2} *)

This is particularly useful if you start using nested Ruled data sets.

$\endgroup$
3
  • $\begingroup$ I can't do that because the data comes from a file. Plus I have many other rows in list1 so associations one by one wouldn't work. $\endgroup$
    – Sulli
    Mar 26, 2013 at 13:44
  • $\begingroup$ @SullivanOrlean I agree with Yves, in that another structure is may be nicer. Rules are nice because it is nice to have a seperate wrapper having the header as its first argument and your actual data as its second element, as this will prevent the copying of the data in the memory in the case you want to take an entire column of the data. However, how to construct such a new structure programmatically from your file, seems to be a job that you can only do once you know the answer to your question. $\endgroup$ Mar 26, 2013 at 13:55
  • 1
    $\begingroup$ @SullivanOrlean The conversion for your example is easy: data = Rule @@@ Thread[list1]. But if you data is more complex, update your example to get suggestions. $\endgroup$
    – Yves Klett
    Mar 26, 2013 at 13:57
0
$\begingroup$

You speak about columns, so I considered the case where you may have more data than 1 element in your columns. This really only extends Yves answer to this case and contains an extra remark about your whatColumn function.

If your data is structured like this (and you have no influence over how this data is made, you just have to deal with it)

fromFile = {{"header1", "header2", "header3"}, {11, 12, 13}, {21, 22, 
   23}};

And you want to select columns (frequently), you can restructure your data as

headers = fromFile[[1]];
ruleList = Rule @@@ Partition[
  Riffle[headers, Transpose[Drop[fromFile, 1]]], 2]

Then you can take the column corresponding to header x, in this case 1, by

header1/. ruleList

Note that your whatColumn function can be simply written as

whatColumn[header_String] := Position[headers, header][[1, 1]]
$\endgroup$

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.