# How do I find the number of countries that have a type of industry?

I am trying to find the number of countries that have a certain type of industry.

Currently, I have this code:

countries = Flatten[CountryData[]];

listofCountries = Table[countries[[i]], {i, 1, 240}];

industries = Map[{CountryData[#, "MajorIndustries"]} &, CountryData[All]];

data = Table[industries[[i]] -> listofCountries[[i]], {i, 1, 240}];


I am not sure on how to find the number of countries that have an industry (i.e. Coal), or if I am headed in the correct direction.

Could somebody show me the correct way to find the number of countries with an industry?

EDIT: If I were trying to shade in the countries found on the world map with a color, how would I do so? (This is using the CountryData function.) I'm curious to see how much of the world has this industry, and so forth. (EDIT: How could I do it with the world map showing the boundaries of every country?)

EDIT 2: How could I do the edit above with two industries? (i.e. Coal and Copper)

-

Here's another way:

Select[CountryData[],
Not @ FreeQ[CountryData[#, "MajorIndustries"], "Coal"] &] // Length


13

OR

Cases[CountryData[#, "MajorIndustries"] & /@ CountryData, {___, "Coal", ___}] // Length


You can also display the countries in question:

Select[countries,
Not[FreeQ[CountryData[#, "MajorIndustries"], "Coal"]] &]


Here they are:

{"Afghanistan", "BosniaHerzegovina", "China", "Colombia", "Germany", \
"Kazakhstan", "Nigeria", "Poland", "Russia", "Swaziland", "Ukraine", \
"UnitedKingdom", "Vietnam"}


If you want to visualize them as in your edited question, do the following:

Graphics[{EdgeForm[Black], If[MemberQ[CountryData[#, "MajorIndustries"], "Coal"], Red, LightBrown],
CountryData[#, "SchematicPolygon"]} & /@ CountryData[]]


Graphics[{EdgeForm[Black],
Which[MemberQ[CountryData[#, "MajorIndustries"], "Coal"], Red,
MemberQ[CountryData[#, "MajorIndustries"], "Copper"], Blue,
True, White], CountryData[#, "FullPolygon"]} & /@ CountryData[]]


Here, red represents coal countries and blue represents copper countries. To get the number of countries that have either coal or copper industry do:

Select[countries, MemberQ[CountryData[#, "MajorIndustries"], "Coal"] ||
MemberQ[CountryData[#, "MajorIndustries"], "Copper"] &] // Length


This gives:

20

-
Thanks! How would I do the question I edited in? –  user9876 Oct 7 '13 at 7:30
@RunnyKine OK. Just wondering, what calamity is behind disappearance of Alaska on these maps? :) –  kirma Oct 7 '13 at 9:31
@MikeHoneychurch I noticed the "CIA World Factbook" did the same thing. Didn't mention copper for Peru, but did mention "mining". And if you look up mining in CountryData, then indeed Peru is included. So perhaps it's the way people who work with stats categorize things that isn't intuitive, it doesn't mean it's not correct/up to date The factbook puts copper in the mining category for Congo as well, but puts "copper mining" on its own for Zambia. –  Pickett Oct 7 '13 at 12:33
@kirma So it seems using FullPolygon brings back Alaska. –  RunnyKine Oct 7 '13 at 17:29
@anon We need the NSA factbook, they know everything... –  cormullion Oct 7 '13 at 18:27
Count[Flatten[
CountryData[#, "MajorIndustries"] & /@ CountryData[]], "Coal"]


13

-

Your first approach, using rules, I think is not a bad idea. Here's one way to implement a rules-based solution:

hasIndustry[industry_] := Select[CountryData[], MemberQ[CountryData[#, "MajorIndustries"], industry] &]
industries = Union @@ (CountryData[#, "MajorIndustries"] & /@ CountryData[] /. _Missing -> Sequence[]);
countryIndustries = Dispatch[# -> hasIndustry[#] & /@ industries];


This sets up a list of rules such that "Coal" /. countryIndustries returns all countries that have coal as a major industry. We've used Dispatch on the list so it should be super fast.

Utilitary functions:

hasEither[list_List] := Union @@ (# /. countryIndustries & /@ list)
hasAll[list_List] := Intersection @@ (# /. countryIndustries & /@ list)


So to sum it up, if we want to know what countries have x as a major industry, we used hasIndustry. If we want to know all the countries to have any of {x,y,z} as a major industry, we used hasEither and if we want to select only the countries that have all of {x,y,z} as major industries we use hasAll.

hasAll[{"Carpets", "BuildingMaterials"}]


{"Afghanistan", "Nepal"}

To know how many countries fulfill a certain criteria, we simply use Length the same way RunnyKine has.

RunnyKine has already provided a great answer, I'm just sort of recreating it but differently for the fun of it. So I wrote this as well:

bg = Graphics[{
RGBColor[0.896, 0.8878, 0.8548], EdgeForm[GrayLevel[0]],
CountryData[#, "FullPolygon"] & /@ CountryData[]
}, ImageSize -> 1000];
highlight[industry_] := Graphics[{
Red, EdgeForm[GrayLevel[0]],
CountryData[#, "FullPolygon"] & /@ hasIndustry[industry]
}];
Manipulate[Show[bg, highlight[industry]], {industry, industries}]


I wrote another post that deals with maps and interactivity, that you may be interested in. You can find it here.

-

We can approach this with v10 functionalities quite nicely:

countries = EntityList@EntityClass["Country", "Countries"];
coal = Select[countries, MemberQ[CountryData[#, "MajorIndustries"], "Coal"] &]


Use Length to get the number if so desired.

copper = Select[countries, MemberQ[CountryData[#, "MajorIndustries"], "Copper"] &]


 GeoGraphics[{EdgeForm[Black], GeoStyling["OutlineMap", Red],
Polygon[coal], GeoStyling["OutlineMap", Blue], Polygon[copper]},
ImageSize -> 800]


OR without background:

GeoGraphics[{EdgeForm[Black], Polygon[countries],
GeoStyling["OutlineMap", Red], Polygon[coal],
GeoStyling["OutlineMap", Blue], Polygon[copper]}, ImageSize -> 800,
GeoBackground -> None]
`

-