7
$\begingroup$

With Mathematica 12, I can create implicit Entity Classes like:

enter image description here

I can also filter for having exactly a specific property, like so enter image description here

It seems quite trivial, but I can't seem to filter by a property not having some value. For example, I'd like to be able to say

EntityClass["Country", "Continent" -> Not["Europe"]]

or something like that.

The documentation for EntityClass lists the following operators to be working with this syntax:

Property values in implicitly defined entity classes may make use of Quantity (and intervals of Quantity) for dimensional values, Between for numeric values, DateObject for dates, TakeLargest and TakeSmallest for ordinal selections, and ContainsAll, ContainsExactly, ContainsAny, ContainsOnly, ContainsNone for entities. Lists of entities are interpreted as ContainsAll, while a single entity is interpreted as ContainsAny[{entity}].

Non of the listed properties looks like it does what I want, i.e. querying for not.

$\endgroup$
7
$\begingroup$

You can use the operator UnequalTo for this purpose:

EntityList @ EntityClass["Country", "Continent"->UnequalTo["Europe"]]

{Entity["Country", "Afghanistan"], Entity["Country", "Algeria"], Entity["Country", "AmericanSamoa"], Entity["Country", "Angola"], Entity["Country", "Anguilla"], Entity["Country", "Antarctica"], Entity["Country", "AntiguaBarbuda"], Entity["Country", "Argentina"], Entity["Country", "Armenia"], Entity["Country", "Aruba"], Entity["Country", "Australia"], Entity["Country", "Azerbaijan"], Entity["Country", "Bahamas"], Entity["Country", "Bahrain"], Entity["Country", "Bangladesh"], Entity["Country", "Barbados"], Entity["Country", "Belize"], Entity["Country", "Benin"], Entity["Country", "Bermuda"], Entity["Country", "Bhutan"], Entity["Country", "Bolivia"], Entity["Country", "BonaireSintEustatiusAndSaba"], Entity["Country", "Botswana"], Entity["Country", "Brazil"], Entity["Country", "BritishVirginIslands"], Entity["Country", "Brunei"], Entity["Country", "BurkinaFaso"], Entity["Country", "Burundi"], Entity["Country", "Cambodia"], Entity["Country", "Cameroon"], Entity["Country", "Canada"], Entity["Country", "CapeVerde"], Entity["Country", "CaymanIslands"], Entity["Country", "CentralAfricanRepublic"], Entity["Country", "Chad"], Entity["Country", "Chile"], Entity["Country", "China"], Entity["Country", "ChristmasIsland"], Entity["Country", "CocosKeelingIslands"], Entity["Country", "Colombia"], Entity["Country", "Comoros"], Entity["Country", "CookIslands"], Entity["Country", "CostaRica"], Entity["Country", "Cuba"], Entity["Country", "Curacao"], Entity["Country", "Cyprus"], Entity["Country", "DemocraticRepublicCongo"], Entity["Country", "Djibouti"], Entity["Country", "Dominica"], Entity["Country", "DominicanRepublic"], Entity["Country", "EastTimor"], Entity["Country", "Ecuador"], Entity["Country", "Egypt"], Entity["Country", "ElSalvador"], Entity["Country", "EquatorialGuinea"], Entity["Country", "Eritrea"], Entity["Country", "Ethiopia"], Entity["Country", "FalklandIslands"], Entity["Country", "Fiji"], Entity["Country", "FrenchGuiana"], Entity["Country", "FrenchPolynesia"], Entity["Country", "Gabon"], Entity["Country", "Gambia"], Entity["Country", "GazaStrip"], Entity["Country", "Georgia"], Entity["Country", "Ghana"], Entity["Country", "Greenland"], Entity["Country", "Grenada"], Entity["Country", "Guadeloupe"], Entity["Country", "Guam"], Entity["Country", "Guatemala"], Entity["Country", "Guinea"], Entity["Country", "GuineaBissau"], Entity["Country", "Guyana"], Entity["Country", "Haiti"], Entity["Country", "Honduras"], Entity["Country", "HongKong"], Entity["Country", "India"], Entity["Country", "Indonesia"], Entity["Country", "Iran"], Entity["Country", "Iraq"], Entity["Country", "Israel"], Entity["Country", "IvoryCoast"], Entity["Country", "Jamaica"], Entity["Country", "Japan"], Entity["Country", "Jordan"], Entity["Country", "Kazakhstan"], Entity["Country", "Kenya"], Entity["Country", "Kiribati"], Entity["Country", "Kuwait"], Entity["Country", "Kyrgyzstan"], Entity["Country", "Laos"], Entity["Country", "Lebanon"], Entity["Country", "Lesotho"], Entity["Country", "Liberia"], Entity["Country", "Libya"], Entity["Country", "Macau"], Entity["Country", "Madagascar"], Entity["Country", "Malawi"], Entity["Country", "Malaysia"], Entity["Country", "Maldives"], Entity["Country", "Mali"], Entity["Country", "MarshallIslands"], Entity["Country", "Martinique"], Entity["Country", "Mauritania"], Entity["Country", "Mauritius"], Entity["Country", "Mayotte"], Entity["Country", "Mexico"], Entity["Country", "Micronesia"], Entity["Country", "Mongolia"], Entity["Country", "Montserrat"], Entity["Country", "Morocco"], Entity["Country", "Mozambique"], Entity["Country", "Myanmar"], Entity["Country", "Namibia"], Entity["Country", "Nauru"], Entity["Country", "Nepal"], Entity["Country", "NewCaledonia"], Entity["Country", "NewZealand"], Entity["Country", "Nicaragua"], Entity["Country", "Niger"], Entity["Country", "Nigeria"], Entity["Country", "Niue"], Entity["Country", "NorfolkIsland"], Entity["Country", "NorthernMarianaIslands"], Entity["Country", "NorthKorea"], Entity["Country", "Oman"], Entity["Country", "Pakistan"], Entity["Country", "Palau"], Entity["Country", "Panama"], Entity["Country", "PapuaNewGuinea"], Entity["Country", "Paraguay"], Entity["Country", "Peru"], Entity["Country", "Philippines"], Entity["Country", "PitcairnIslands"], Entity["Country", "PuertoRico"], Entity["Country", "Qatar"], Entity["Country", "RepublicCongo"], Entity["Country", "Reunion"], Entity["Country", "Russia"], Entity["Country", "Rwanda"], Entity["Country", "SaintBarthelemy"], Entity["Country", "SaintHelena"], Entity["Country", "SaintKittsNevis"], Entity["Country", "SaintLucia"], Entity["Country", "SaintMartin"], Entity["Country", "SaintPierreMiquelon"], Entity["Country", "SaintVincentGrenadines"], Entity["Country", "Samoa"], Entity["Country", "SaoTomePrincipe"], Entity["Country", "SaudiArabia"], Entity["Country", "Senegal"], Entity["Country", "Seychelles"], Entity["Country", "SierraLeone"], Entity["Country", "Singapore"], Entity["Country", "SintMaarten"], Entity["Country", "SolomonIslands"], Entity["Country", "Somalia"], Entity["Country", "SouthAfrica"], Entity["Country", "SouthKorea"], Entity["Country", "SouthSudan"], Entity["Country", "SriLanka"], Entity["Country", "Sudan"], Entity["Country", "Suriname"], Entity["Country", "Swaziland"], Entity["Country", "Syria"], Entity["Country", "Taiwan"], Entity["Country", "Tajikistan"], Entity["Country", "Tanzania"], Entity["Country", "Thailand"], Entity["Country", "Togo"], Entity["Country", "Tokelau"], Entity["Country", "Tonga"], Entity["Country", "TrinidadTobago"], Entity["Country", "Tunisia"], Entity["Country", "Turkey"], Entity["Country", "Turkmenistan"], Entity["Country", "TurksCaicosIslands"], Entity["Country", "Tuvalu"], Entity["Country", "Uganda"], Entity["Country", "UnitedArabEmirates"], Entity["Country", "UnitedStates"], Entity["Country", "UnitedStatesVirginIslands"], Entity["Country", "Uruguay"], Entity["Country", "Uzbekistan"], Entity["Country", "Vanuatu"], Entity["Country", "Venezuela"], Entity["Country", "Vietnam"], Entity["Country", "WallisFutuna"], Entity["Country", "WestBank"], Entity["Country", "WesternSahara"], Entity["Country", "Yemen"], Entity["Country", "Zambia"], Entity["Country", "Zimbabwe"]}

Addendum

For excluding multiple value, you could use the following syntax:

EntityList @ EntityClass["Country",
    {
    "Continent"->UnequalTo["Europe"],
    "Continent"->UnequalTo["Asia"]
    }
] //Length

139

| improve this answer | |
$\endgroup$
  • $\begingroup$ Fantastic. Thanks. Any idea how to expand that to multiple values, like UnequalTo[{"Europe","Asia"}] or so? It would seem that ContainsNone or a related operator would work, but it doesn't. $\endgroup$ – Stephan Oct 18 '19 at 15:22
  • $\begingroup$ Just briefly: Which other Operators work with implicit EntityClasses that do not appear in the Documentation? Is there a list, or is it based on some property of the allowed operators? $\endgroup$ – Stephan Oct 18 '19 at 20:12
7
$\begingroup$

Alternative solution with FilteredEntityClass and EntityFunction

The code

For the sake of documenting this one more time on this site, a more general answer (w.r.t. the answer of Carl) would be to use EntityFunction and FilteredEntityClass. In this particular case, one additional subtlety is that in this method, one has to compare the "Continent" property with EntityClass["Country", "Europe"], rather than a string "Europe".

Here is the code

nonEuropeanCountries = EntityList @ FilteredEntityClass[
  "Country",
   EntityFunction[
     c, 
     c["Continent"] =!=  EntityClass["Country", "Europe"]
   ]
]

Differences with the operator-based method

Note that this result will be different from that obtained with Carl's code, since this one keeps the countries for which the continent is not defined, while Carl's code throws them away:

Complement[
  nonEuropeanCountries, 
  EntityList @ EntityClass["Country", "Continent" -> UnequalTo["Europe"]]
]

(*
{
  Entity["Country", "BouvetIsland"], 
  Entity["Country", "BritishIndianOceanTerritory"], 
  Entity["Country", "FrenchSouthernAndAntarcticLands"], 
  Entity["Country", "SouthGeorgiaAndTheSouthSandwichIslands"], 
  Entity["Country", "UnitedStatesMinorOutlyingIslands"]
}
*)

Which behavior is more desired, depends on the situation, but it is important to keep in mind this difference. Also, while one can filter such countries out from the above solution, one can't reconstruct those back from the one based on operators.

More on EntityFunction

In general, EntityFunction is a somewhat more verbose, but also significantly more powerful device, than the short-hand syntax based on rules, since one can create predicates which couple together more than one entity property - which is in general impossible in the short syntax (except cases when the full predicate can be expressed via individual property predicates combined using simple And condition).

Here is an example that would be pretty hard to express in the short syntax, within a single query: find all countries which either are in Europe and their names start with "A", or have population higher than 100 million people. Here is the code for this using EntityFunction:

EntityList @ FilteredEntityClass[
  "Country",
  EntityFunction[c, 
    Or[
      And[
        c["Continent"] ===  EntityClass["Country", "Europe"], 
        StringStartsQ[c["Name"], "A"]
      ],
      c["Population"] > Quantity[10^8, "People"]
    ]
  ]
]

(*

{
  Entity["Country", "AlandIslands"], Entity["Country", "Albania"], 
  Entity["Country", "Andorra"], Entity["Country", "Austria"], 
  Entity["Country", "Bangladesh"], Entity["Country", "Brazil"], 
  Entity["Country", "China"], Entity["Country", "Ethiopia"], 
  Entity["Country", "India"], Entity["Country", "Indonesia"], 
  Entity["Country", "Japan"], Entity["Country", "Mexico"], 
  Entity["Country", "Nigeria"], Entity["Country", "Pakistan"], 
  Entity["Country", "Philippines"], Entity["Country", "Russia"], 
  Entity["Country", "UnitedStates"]
}
*)
| improve this answer | |
$\endgroup$
  • 1
    $\begingroup$ Thanks for taking the time to post another answer. Yes, I knew about FilteredEntityClass and should have mentioned it as an alternative solution that I already knew about. The reason I wanted to know a solution using EntityClass was that I was hoping that that is faster... simply due to the fact that it restricts functionality to a few selected operators which perhaps are better optimized with the DB-backend than the far more general EntityFunction. Am I wrong? $\endgroup$ – Stephan Oct 18 '19 at 20:09
  • 2
    $\begingroup$ For the DB backend this is all the same, the short form is simply compiled to the long one. EntityFunction gets compiled in all cases, for the db backend (we do not support callbacks from db to the kernel, so if we can't compile EntityFunction completely, we throw an error). Trust me, I co-wrote the db compiler :). $\endgroup$ – Leonid Shifrin Oct 18 '19 at 20:11
  • $\begingroup$ OK, thanks. I do trust you, I've followed some of the livestreams by Stephen Wolfram and listened to you and others on the team about this whole DB-development with much interest... yes, I had too much time. $\endgroup$ – Stephan Oct 18 '19 at 20:15
  • $\begingroup$ All right. I was just kidding :) $\endgroup$ – Leonid Shifrin Oct 18 '19 at 20:16
  • $\begingroup$ Congratulations on reaching 100k, Leonid! :) $\endgroup$ – Andreas Rejbrand Oct 19 '19 at 22:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.