Motivation
Another approach is to convert your data into an Association
. It might involve one or two steps beforehand but in my opinion, it makes for safer and more legible code in the long run.
It has numerous advantages over working on a List
but the one I find most useful is that I can call a column by its name instead of its index.
For example, your code is more legible with
someBigDataAssociation[[All,"EyeColour"]]
compared to
someBigDataList[[All,42]]
It also makes your code more resilient, what if your data changed and "EyeColour" is no longer in column 42?
Helper Functions
First, we define some helper functions to move between associations and tables with headers.
(* helper functions *)
convertTableWithHeaderToAssociation[table_List] :=
Module[
{
header = First[table],
body = Rest[table]
},
AssociationThread[header, #] & /@ body
];
convertAssociationToTableWithHeader[association_List] :=
Module[
{
header = {First[Keys[association]]},
body = Values[association]
},
header~Join~body
];
Answer
Convert your data to an Association
birthAndDeathYear = convertTableWithHeaderToAssociation[lis]
{<|"YOB" -> 1910, "status" -> 1982|>, <|"YOB" -> 1977,
"status" -> "ALIVE"|>, <|"YOB" -> 1951,
"status" -> 2012|>, <|"YOB" -> 1977, "status" -> "ALIVE"|>}
Now we redefine the "status"
column applying our NumericQ
rule to #status
(see Note)
birthAndDeathStatus = <|#,
"status" -> If[NumericQ[#status], "DEAD", #status]|> & /@
birthAndDeathYear
{<|"YOB" -> 1910, "status" -> "DEAD"|>, <|"YOB" -> 1977,
"status" -> "ALIVE"|>, <|"YOB" -> 1951,
"status" -> "DEAD"|>, <|"YOB" -> 1977, "status" -> "ALIVE"|>}
Depending on what you want to do with this data next, you can :
inspect it with Dataset
...
...or TableForm
...
or return it to the original format, perhaps to Export
it later
convertAssociationToTableWithHeader[birthAndDeathYear]
{{"YOB", "status"}, {1910, 1982}, {1977, "ALIVE"}, {1951,
2012}, {1977, "ALIVE"}}
Note
This makes use of the fact that "Associations keep only the last instance of repeated keys"
for example
<|"a" -> 1, "b" -> 2, "b" -> "bar"|>
<|"a" -> 1, "b" -> "bar"|>
For more information on working with Associations
(and Dataset
), I found this answer from WReach very helpful.
lis /. {yrS_, yrF_?NumericQ} :> {yrS, "DEAD"}
$\endgroup$RuleDelayed
that would replace something with a replacement. Then defines the something as a list with two elements, the first can be anything, but the second must be a number. All those lists are replaced by their same first element and as a second element the word "DEAD." Beautiful!Rule
seems to work just as well asRuleDelayed
for me, so he might explain if the latter has some advantage that I don't see. $\endgroup$Rule
orRuleDelayed
in this case. I just tend to useRuleDelayed
unless there is a reason not to. $\endgroup$