# Deleting parts of a large list

At present I am running an analysis on economic data. Within the data I was able to identify countries which went through recession. I then calculated for example the average decline rate of GDP during recession. All my results are in the following list:

CompleteQuarterlyStatData


In this list I had to keep also all the countries which did not go through a recession. So if I ask for the decline rate of Australia during recession I get the following answer:

In[1328]:= CompleteQuarterlyStatData[[1]][[1]][[1]]

Out[1328]= {{"Australia", "AUS", "other countries", "GDP","quarterly data"}, {}}


Whereas position 1 (CompleteQuarterlyStatData[[i]]) indicates the key figure (in the above example "decline rate during recession"), position 2 (CompleteQuarterlyStatData[[i]][[j]]) the economic indicator (in the above example "GDP") and position 3 (CompleteQuarterlyStatData[[i]][[j]][[k]]) the country (in the above example "Australia").

(by the way: In total I have nine key figures (so i ranges from 1 to 9), 24 economic indicators (j ranges from 1 to 24) and 32 countries (k ranges from 1 to 32))

As Australia obviously did not got through a recession I want to get rid of all key figures for Australian GDP, which works with the following code:

If[
NumberQ[CompleteQuarterlyStatData[[1]][[1]][[2]][[2]]] == False,
Table[
Delete[CompleteQuarterlyStatData, i],
{i,
Map[
Part[#, 1 ;; 3] &,
Position[CompleteQuarterlyStatData,CompleteQuarterlyStatData[[1]][[1]][[2]][[1]]]]
}
]
];


(Note: Position 2 of CompleteQuarterlyStatData[[1]][[1]][[2]] is {} and CompleteQuarterlyStatData[[1]][[1]][[2]] {"Australia", "AUS", "other countries", "GDP","quarterly data"}. (see Out[1328]))

So what all countries, which did not go through a recession or a longterm decline, have in common is, that CompleteQuarterlyStatData[[1]][[EcoIndicator]][[Country]][[2]] is always of the value {}.

(Note: CompleteQuarterlyStatData[[1]] refers to the key figure "decline rate during recession".)

To get rid of all countries which did not suffer from a longterm decline in a given economic indicator I could wrap Table around my if-procedure to go through all economic indicators and countries:

Table[
Table[
If[
NumberQ[CompleteQuarterlyStatData[[1]][[EcoIndicator]][[Country]][[2]]] == False,
Table[
Delete[CompleteQuarterlyStatData, i],
{i,
Map[
Part[#, 1 ;; 3] &,
Position[CompleteQuarterlyStatData,CompleteQuarterlyStatData[[1]][[EcoIndicator]][[Country]][[1]]]]
}
]
]
,{Country,Length[CompleteQuarterlyStatData[[1]][[EcoIndicator]]]}]
,{EcoIndicator,Length[CompleteQuarterlyStatData[[1]]]}];


But that does not work. Does anyone has a suggestion?

In fact it would be nice to have something like Delete[CompleteQuarterlyStatData,ArrayXXX] whereas ArrayXXX represents the position of all countries (which did not go through a longterm decline) within CompleteQuarterlyStatData.

For better understanding I created an example:

list = {
{
{{{"Australia","GDP"},{}}, {{"Korea","GDP"},-2.45}, {{"USA","GDP"},-2.34}},
{{{"Australia","GDP"},2.34}, {{"Korea","GDP"},1.23}, {{"USA","GDP"},1.45}}
},
{
{{{"Greece", "Imports"},3.25}, {{"Turkey","Imports"}, {}}, {{"USA","Imports"},-2.64}},
{{{"Greece", "Imports"},-1.23}, {{"Turkey","Imports"},3.56}, {{"USA","Imports"},-1.56}}
}
};


The output of list[[1]][[1]][[1]] or list[[2]][[1]][[2]] matches the pattern {_,{}}. In that case I would like not only to delete those parts of list witch matches the pattern {_,{}} but also all other key figures which were calculated for the individual country and economic indicator. The result should then be:

{
{
{{{"Korea","GDP"},-2.45}, {{"USA","GDP"},-2.34}},
{{{"Korea","GDP"},1.23}, {{"USA","GDP"},1.45}}
},
{
{{{"Greece", "Imports"},3.25}, {{"USA","Imports"},-2.64}},
{{{"Greece", "Imports"},-1.23}, {{"USA","Imports"},-1.56}}
}
};


The reason: Australia did not go through a longterm decline in GDP, neither did Turkey in imports (if so, all other key figures concerning Australia & GDP or Turkey & imports would be irrelevant for further calculation).

-
My +1 is not just because you mentioned GDP in Australia, but it helps :) – Verbeia Mar 9 '12 at 0:19
As a general coding style comment, I would suggest that you replace all those sets of double-brackets [[1]][[1]][[1]] with the equivalent [[1, 1, 1]]. It will be much easier to read. – Verbeia Mar 9 '12 at 0:26
I wasn't aware of [[1,1,1]] is equivalent to [[1]][[1]][[1]]. Thanks! – John Mar 9 '12 at 9:20
Not uncommon - when looking at old code of mine I cannot help wincing at those bracket chains (mind you, it worked just fine). – Yves Klett Mar 9 '12 at 11:00

I think that one of the reasons your code isn't working is that Delete doesn't actually modify the original list so during every iteration in your Table you're actually working with the original list, not the one that was returned from the previous iteration. One way to solve this is to set CompleteQuarterlyStatData to the result of Delete in every iteration but a more functional way would be to do something like this instead

DeleteCases[CompleteQuarterlyStatData, {_, {}}, {3}]


I would suggest that you familiarise yourself with the use of Patterns in Mathematica.

Edit

This is probably not the most efficient method, but you could try something like. It seems to work for the example posted by the OP at least.

list = {
{
{{{"Australia", "GDP"}, {}}, {{"Korea", "GDP"}, -2.45},
{{"USA", "GDP"}, -2.34}},
{{{"Australia", "GDP"}, 2.34}, {{"Korea", "GDP"}, 1.23},
{{"USA", "GDP"}, 1.45}}},
{
{{{"Greece", "Imports"}, 3.25}, {{"Turkey", "Imports"}, {}},
{{"USA", "Imports"}, -2.64}},
{{{"Greece", "Imports"}, -1.23}, {{"Turkey", "Imports"}, 3.56},
{{"USA", "Imports"}, -1.56}}
}
};

DeleteCases[list, Alternatives @@ Cases[list, {a_, {}} :> {a, _}, {3}], {3}]

{
{
{{{"Korea", "GDP"}, -2.45}, {{"USA", "GDP"}, -2.34}},
{{{"Korea", "GDP"}, 1.23}, {{"USA", "GDP"}, 1.45}}},
{
{{{"Greece", "Imports"}, 3.25}, {{"USA", "Imports"}, -2.64}},
{{{"Greece", "Imports"}, -1.23}, {{"USA", "Imports"}, -1.56}}
}
}

-
@John I can't see your example. Maybe you can post it in your original question. – Heike Mar 9 '12 at 10:06
Unfortunately that does not solve the problem, as I don't only want to delete elements which match the pattern {_, {}}. Please take a look at my answer. – John Mar 9 '12 at 10:20
@John please see edit. – Heike Mar 9 '12 at 10:38
I assume that {3} in DeleteCasesand Cases stands for the level specification within list? – John Mar 9 '12 at 11:39
@John yes, that's right. – Heike Mar 9 '12 at 11:43
show 1 more comment