{"id":43704634,"url":"https://github.com/eurostat/java4eurostat","last_synced_at":"2026-02-05T05:38:12.845Z","repository":{"id":45129729,"uuid":"61204744","full_name":"eurostat/java4eurostat","owner":"eurostat","description":"Multi-dimensional data manipulation and easy access to Eurostat data. In Java.","archived":false,"fork":false,"pushed_at":"2023-04-14T17:13:32.000Z","size":3756,"stargazers_count":7,"open_issues_count":5,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-01-28T02:11:13.283Z","etag":null,"topics":["database","dimension-values","dimensions","eurostat","eurostat-data","eurostat-databases","hypercube","hypercube-structure","java","selection-criteria","statistical-data","tsv"],"latest_commit_sha":null,"homepage":"https://github.com/eurostat/java4eurostat/blob/master/README.md","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"eupl-1.2","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eurostat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-06-15T12:01:44.000Z","updated_at":"2022-07-27T11:55:30.000Z","dependencies_parsed_at":"2022-09-26T22:10:20.207Z","dependency_job_id":"8214b3bd-2674-4b72-9ba5-e895a9297102","html_url":"https://github.com/eurostat/java4eurostat","commit_stats":{"total_commits":340,"total_committers":5,"mean_commits":68.0,"dds":0.361764705882353,"last_synced_commit":"2720c2df773c8906111087009a91ba9ad5c02f23"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/eurostat/java4eurostat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eurostat%2Fjava4eurostat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eurostat%2Fjava4eurostat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eurostat%2Fjava4eurostat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eurostat%2Fjava4eurostat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eurostat","download_url":"https://codeload.github.com/eurostat/java4eurostat/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eurostat%2Fjava4eurostat/sbom","scorecard":{"id":385129,"data":{"date":"2025-08-11","repo":{"name":"github.com/eurostat/java4eurostat","commit":"2720c2df773c8906111087009a91ba9ad5c02f23"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.5,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/26 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: European Union Public License 1.2: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":6,"reason":"4 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-78wr-2p64-hpwj","Warn: Project is vulnerable to: GHSA-j288-q9x7-2f5v","Warn: Project is vulnerable to: GHSA-3vqj-43w4-2q58","Warn: Project is vulnerable to: GHSA-4jq9-2xhw-jpx7"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 5 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T16:24:40.546Z","repository_id":45129729,"created_at":"2025-08-18T16:24:40.546Z","updated_at":"2025-08-18T16:24:40.546Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29113838,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T05:31:32.482Z","status":"ssl_error","status_checked_at":"2026-02-05T05:31:29.075Z","response_time":65,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","dimension-values","dimensions","eurostat","eurostat-data","eurostat-databases","hypercube","hypercube-structure","java","selection-criteria","statistical-data","tsv"],"created_at":"2026-02-05T05:38:09.146Z","updated_at":"2026-02-05T05:38:12.839Z","avatar_url":"https://github.com/eurostat.png","language":"HTML","readme":"# java4eurostat\r\n\r\n[![Maven Central](https://img.shields.io/maven-central/v/eu.europa.ec.eurostat/java4eurostat.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22eu.europa.ec.eurostat%22%20AND%20a:%22java4eurostat%22)\r\n\r\n[Java4eurostat](https://github.com/eurostat/java4eurostat) is a Java library for statistical data manipulation. It provides a number of functions to load statistical data into an 'hypercube' structure and index it for easy and fast in-memory computations. A number of specific functions are provided to easily access [Eurostat](http://ec.europa.eu/eurostat/) data.\r\n\r\n## Quick start\r\n\r\nLet's start with a simple dataset:\r\n\r\n|country|gender|year|population|\r\n|:--:|:--:|:--:| --:|\r\n|Brasil|Male|2013|45.1|\r\n|Brasil|Female|2013|48.3|\r\n|Brasil|Total|2013|93.4|\r\n|Brasil|Male|2014|46.2|\r\n|Brasil|Female|2014|47.7|\r\n|Brasil|Total|2014|93.9|\r\n|Japan|Male|2013|145.1|\r\n|Japan|Female|2013|148.3|\r\n|Japan|Total|2013|293.4|\r\n|Japan|Male|2014|146.2|\r\n|Japan|Female|2014|147.7|\r\n|Japan|Total|2014|293.9|\r\n\r\nstored as a CSV file `example.csv`:\r\n\r\n```\r\ncountry,gender,year,population\r\nBrasil,Male,2013,45.1\r\nBrasil,Female,2013,48.3\r\nBrasil,Total,2013,93.4\r\nBrasil,Male,2014,46.2\r\nBrasil,Female,2014,47.7\r\nBrasil,Total,2014,93.9\r\nJapan,Male,2013,145.1\r\nJapan,Female,2013,148.3\r\nJapan,Total,2013,293.4\r\nJapan,Male,2014,146.2\r\nJapan,Female,2014,147.7\r\nJapan,Total,2014,293.9\r\n```\r\n\r\nThis file can be loaded into an hypercube structure with:\r\n\r\n```java\r\nStatsHypercube hc = CSV.load(\"example.csv\", \"population\");\r\n```\r\n\r\nInformation on the hypercube structure is shown with ```hc.printInfo();```, which returns:\r\n\r\n```\r\nInformation: 12 value(s) with 3 dimension(s).\r\n   Dimension: gender (3 dimension values)\r\n      Female\r\n      Male\r\n      Total\r\n   Dimension: year (2 dimension values)\r\n      2013\r\n      2014\r\n   Dimension: country (2 dimension values)\r\n      Brasil\r\n      Japan\r\n```\r\n\r\nSeveral input formats are supported. For example, [Eurostat](http://ec.europa.eu/eurostat/) data can be loaded directly from the web. For that, only the database code given in [Eurostat databases catalog](http://ec.europa.eu/eurostat/data/database) is required. For example, the database on *HICP - Country weights* (code *prc_hicp_cow*) can be downloaded and loaded simply with:\r\n\r\n```java\r\nStatsHypercube hc2 = EurobaseIO.getData(\"prc_hicp_cow\");\r\n```\r\n\r\nThe structure returned with a ```hc2.printInfo();``` is:\r\n\r\n```\r\nInformation: 2001 value(s) with 3 dimension(s).\r\n   Dimension: time (21 dimension values)\r\n      1996\r\n      1997\r\n      1998\r\n      ...\r\n   Dimension: geo (35 dimension values)\r\n      AT\r\n      BE\r\n      BG\r\n      ...\r\n   Dimension: statinfo (6 dimension values)\r\n      COWEA\r\n      COWEA18\r\n      COWEA19\r\n      ...\r\n```\r\n\r\nOnce loaded, data can be filtered/selected. For example, ```hc.selectDimValueEqualTo(\"country\",\"Brasil\")``` selects data for Brasil and ```hc.selectValueGreaterThan(147)``` selects data with values greater than 147. Selection criteria can be combined in cascade like ```hc.selectDimValueEqualTo(\"country\",\"Brasil\").selectDimValueGreaterThan(\"year\",2012)``` for the selection of Brasil data after 2012. Logical operators 'AND', 'OR' and 'NOT' can also be used to build more complex selection criteria. Totally generic selection criteria can be specified such as:\r\n\r\n```java\r\nhc.select(new Criteria(){\r\n\t@Override\r\n\tpublic boolean keep(Stat stat) {\r\n\t\treturn stat.dims.get(\"country\").contains(\"r\") \u0026\u0026 Math.sqrt(stat.value)\u003e7;\r\n\t}\r\n});\r\n```\r\n\r\nwhich selects all statistics with country names containing a \"r\" character, and whose root square value is greater than 7.\r\n\r\nA single value can be retrieved with for example ```hc.selectDimValueEqualTo(\"country\", \"Japan\", \"gender\", \"Total\", \"year\", \"2014\").stats.iterator().next().value``` but the fastest way to retrieve a value and scan a dataset is to use an index with:\r\n\r\n```java\r\nStatsIndex index = new StatsIndex(hc, \"gender\", \"year\", \"country\");\r\n```\r\nThis index is a tree structure based on the dimension values. This structure can be displayed with ```index.print();```:\r\n\r\n```\r\nTotal\r\n   2014\r\n      Brasil -\u003e 93.9\r\n      Japan -\u003e 293.9\r\n   2013\r\n      Brasil -\u003e 93.4\r\n      Japan -\u003e 293.4\r\nMale\r\n   2014\r\n      Brasil -\u003e 46.2\r\n      Japan -\u003e 146.2\r\n   2013\r\n      Brasil -\u003e 45.1\r\n      Japan -\u003e 145.1\r\nFemale\r\n   2014\r\n      Brasil -\u003e 47.7\r\n      Japan -\u003e 147.7\r\n   2013\r\n      Brasil -\u003e 48.3\r\n      Japan -\u003e 148.3\r\n```\r\n\r\nA statistical value is accessed quickly from the index and its dimension values: ```double value = index.getSingleValue(\"Total\",\"2014\",\"Japan\");```. Scanning a full dataset across its dimensions is very fast with:\r\n\r\n```java\r\nfor(String gender : index.getKeys())\r\n\tfor(String year : index.getKeys(gender))\r\n\t\tfor(String country : index.getKeys(gender,year)) {\r\n\t\t\tSystem.out.println(gender +\" \"+year+\" \"+country);\r\n\t\t\tSystem.out.println(index.getSingleValue(gender,year,country));\r\n\t\t}\r\n```\r\n\r\n## More information\r\n\r\n### Setup\r\n\r\n[Java4eurostat](https://github.com/eurostat/java4eurostat) uses [Apache Maven](http://maven.apache.org/). To use java4eurostat, add it as a dependency to the *pom.xml* file:\r\n\r\n```\r\n\u003cdependency\u003e\r\n\t\u003cgroupId\u003eeu.europa.ec.eurostat\u003c/groupId\u003e\r\n\t\u003cartifactId\u003ejava4eurostat\u003c/artifactId\u003e\r\n\t\u003cversion\u003eX.Y.Z\u003c/version\u003e\r\n\u003c/dependency\u003e\r\n```\r\nWhere *X.Y.Z* is the latest version number, as available [Maven central repository](https://search.maven.org/artifact/eu.europa.ec.eurostat/java4eurostat).\r\n\r\nFor more information on how to setup a coding environment based on Eclipse, see [this page](https://github.com/eurostat/README/blob/master/docs/howto/java_eclipse_maven_git_quick_guide.md).\r\n\r\n### Documentation\r\n\r\nSee the [Javadoc API](https://eurostat.github.io/java4eurostat/src/site/apidocs/).\r\n\r\n### Load/save data\r\n#### CSV\r\n\r\nStatistical data such as:\r\n\r\n```\r\ncountry,gender,year,population\r\nBrasil,Male,2013,45.1\r\nBrasil,Female,2013,48.3\r\nJapan,Total,2013,93.4\r\n...\r\n```\r\n\r\nCan be simply loaded and saved with:\r\n\r\n```java\r\n//load\r\nStatsHypercube hc = CSV.load(\"C:\\datafolder\\myFile.csv\", \"population\");\r\n//save\r\nCSV.save(hc, \"population\", \"C:\\datafolder\\myFile.csv\");\r\n```\r\n\r\nFor tabular data with several value columns such as: \r\n\r\n```\r\ncountry,gender,year,2010,2015,2020\r\nBrasil,Male,2013,45.1,45.1,45.1\r\nBrasil,Total,2013,93.4,45.1,45.1\r\nJapan,Male,2014,46.2,45.1,45.1\r\n...\r\n```\r\n\r\nJust use:\r\n\r\n```java\r\n//load\r\nStatsHypercube hc = CSV.loadMultiValues(\"C:\\datafolder\\myFile.csv\", \"year\", \"2010\", \"2015\", \"2020\");\r\n//save\r\nCSV.saveMultiValues(hc, \"C:\\datafolder\\myFile.csv\", \"year\")\r\n```\r\n\r\n#### TSV and Eurostat data\r\n\r\nThe class ```EurobaseIO``` provides several functions to handle Eurostat data. For example: ```StatsHypercube hc = EurobaseIO.getData(\"prc_hicp_cow\");``` loads the database *prc_hicp_cow*. Selection parameters may also be specified: ```getData(\"prc_hicp_cow\", \"geo\", \"EU\", \"geo\", \"EA\", \"time\", \"2016\")``` returns loads database *prc_hicp_cow* figures for 2016, for both *EU* and *EA*. Additionnaly, ```getData(\"prc_hicp_cow\", \"lastTimePeriod\", \"4\")``` return the figures for the 4 last time periods, while ```getData(\"prc_hicp_cow\", \"sinceTimePeriod\", \"2005\")``` returns all figures since 2005.\r\n\r\nEurostat TSV files can be downloaded manually from [the bulk download facility](http://ec.europa.eu/eurostat/data/bulkdownload) or using:\r\n\r\n```java\r\n//download from Eurostat bulk download facility\r\nEurobaseIO.getDataBulkDownload(\"eurobase_code\",\"/home/datafolder/\");\r\n//load\r\nStatsHypercube hc = EurostatTSV.load(\"/home/datafolder/eurobase_code.tsv\");\r\n//save\r\n//  not implemented (yet)\r\n```\r\n\r\nThe last publication date of a database can be retrieved with ```getUpdateDate```: For example, ```EurobaseIO.getUpdateDate(\"prc_hicp_cow\");``` returns the last publication date of the database with code *prc_hicp_cow*.\r\n\r\nIn case of regular use of some Eurostat databases as TSV files, these files can be downloaded and updated only when new data is published. For example:\r\n\r\n```java\r\nEurobaseIO.update(\"C:/my_data_folder/\", \"my_database_code1\", \"my_database_code2\", \"my_database_code3\", ...);\r\n```\r\n\r\nretrieves new files *my_database_code1.tsv*, *my_database_code2.tsv* and *my_database_code3.tsv* only when they has been updated. This function creates a file ```update.txt``` in ```C:/my_data_folder/``` folder, which gives the last update dates of the files. \r\n\r\nCode list dictionnaries are loaded with for example ```EurobaseIO.getDictionnary(\"geo\")``` which retrieve the dictionnary of geographical locations (code *geo*). ```EurobaseIO.getDictionnary(\"geo\").get(\"IT\")``` returns \"Italy\". Last update dates are retreved with for example ```getDictionnaryUpdateDate(\"geo\")```.\r\n\r\n#### JSON-stat\r\n\r\nFor [JSON-stat](https://json-stat.org/) data, simply use:\r\n\r\n```java\r\n//load\r\nString jsonStatString = '{\"version\":\"2.0\", \"class\":\"dataset\", \"label\":\"Population data\", \"source\":\"\", \"id\":[...], \"size\":[...], \"dimension\":{...}, \"value\":[...]}';\r\nStatsHypercube hc = JSONStat.load(jsonStatString);\r\n//save\r\n//  not implemented (yet)\r\n```\r\n\r\n#### Filtering on loading\r\nTo ensure an efficient usage of memory, a selection criteria can be specified when loading from a data source. For example, ```StatsHypercube hc = EurobaseIO.getData(\"prc_hicp_cow\", new DimValueEqualTo(\"geo\",\"BG\"))``` loads only data for country *BG*.\r\n\r\n### Base data structures\r\n\r\nThe base classes are ```Stat``` and  ```StatsHypercube```. A ```Stat``` object represents a statistical value, which is stored as an element of the ```StatsHypercube``` structure.\r\n\r\nA ```Stat``` object is characterised by its value (of course) and its position in the hypercube, which is represented as a dictionnary of pairs *(dimension label, dimension value)*, which represents its coordinates within the hypercube. [Flags](http://ec.europa.eu/eurostat/data/database/information) can also be attached to a statistical value. The class ```StatsHypercube``` is simply characterised by its collection of ```Stat``` elements and dimension names.\r\n\r\n[TODO: describe HierarchicalCode]\r\n\r\n### Data access and selection\r\n\r\nData of a hypercube are accessed using either the ```StatsHypercube.select()``` method or a ```StatsIndex``` object. Access with a ```StatsIndex``` is faster, but requires the construction of an index object, which can be resource consumming.\r\n\r\nBasic operations based on selection and indexing are presented in the quick start section above.\r\n\r\n[TODO: extend description.]\r\n\r\nThe class ```Selection``` provide various ways to navigate in the hypercube structure hy selecting specific values based on various criteria. \r\n\r\n### Operations\r\n\r\nOperations can be quickly applied on statistical values of a hypercube, such as:\r\n\r\n```java\r\n//divide all values by 100.\r\nhc.div(100);\r\n//add 0.185 to all values.\r\nhc.add(0.185);\r\n```\r\n\r\nIt is also possible to combine values of two hypercubes for example:\r\n\r\n```java\r\n//get population data for 2020 and 2010\r\nStatsHypercube hcPop2020 = ...;\r\nStatsHypercube hcPop2010 = ...;\r\n//compute population change\r\nStatsHypercube hcPopChange = hcPop2020.diff(hcPop2010);\r\n```\r\n\r\nThese operation can easily be combined:\r\n\r\n```java\r\n//get population data for 2020 and 2010\r\nStatsHypercube hcPop2020 = ...;\r\nStatsHypercube hcPop2010 = ...;\r\n//compute population rate of change, in percentage\r\nStatsHypercube hcPopRateOfChange = hcPop2020.diff(hcPop2010).div(hcPop2010).mult(100);\r\n```\r\n\r\nNew statistical values can also be computed from existing hypercube values. For example, to compute the total value along a dimension ```age_group```:\r\n\r\n```java\r\n//get population data by age group\r\nStatsHypercube hcPopByAge = ...;\r\nCollection\u003cStat\u003e totals = Operations.computeSumDim(hcPopByAge, \"age_group\", \"TOTAL\");\r\nhcPopByAge.stats.addAll(totals);\r\n```\r\n\r\nMore operations are available from the ```Operations``` class. Custom [unary](https://en.wikipedia.org/wiki/Unary_operation), [binary](https://en.wikipedia.org/wiki/Binary_operation) or [aggregation](https://en.wikipedia.org/wiki/Aggregate_function) operators can be implemented.\r\n\r\n### Compacity\r\n\r\nThe class ```Compacity``` provides various methods to analyse how full/empty the hypercube structure is. This compacity computation can be restrictied to single dimensions, which gives a good overview of the completness of the input data and along which dimension it is worth focussing on. See for example the ```Compacity.getDimensionValuesByCompacity``` method.\r\n\r\n### Validation\r\n\r\nThe class ```Validation``` provides various methods to check the compliance of the dimension codes with some specified values (```Validation.Compacity.checkDimensionValuesValidity``` method). The ```Validation.Compacity.checkUnicity``` methods also checks the unicity of statistical values per position in the hypercube.\r\n\r\n### Time series analysis\r\n\r\nThe class ```TimeSeriesUtil``` provides several function for time series analysis such as the computation of moving averages, gap analysis and outlier values detection.\r\n\r\n[TODO: extend description.]\r\n\r\n## Support and contribution\r\n\r\nFeel free to [ask support](https://github.com/eurostat/java4eurostat/issues/new), fork the project or simply star it (it's always a pleasure).\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feurostat%2Fjava4eurostat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feurostat%2Fjava4eurostat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feurostat%2Fjava4eurostat/lists"}