{"id":32181577,"url":"https://github.com/ngrunwald/meta-csv","last_synced_at":"2026-02-24T04:02:25.749Z","repository":{"id":62433628,"uuid":"192710372","full_name":"ngrunwald/meta-csv","owner":"ngrunwald","description":"A Clojure smart reader for CSV files","archived":false,"fork":false,"pushed_at":"2022-09-03T13:29:08.000Z","size":50,"stargazers_count":28,"open_issues_count":5,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-11-22T21:08:06.879Z","etag":null,"topics":["csv","data-analysis"],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ngrunwald.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-19T10:24:30.000Z","updated_at":"2025-06-04T20:51:38.000Z","dependencies_parsed_at":"2022-11-01T21:01:50.388Z","dependency_job_id":null,"html_url":"https://github.com/ngrunwald/meta-csv","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/ngrunwald/meta-csv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngrunwald%2Fmeta-csv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngrunwald%2Fmeta-csv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngrunwald%2Fmeta-csv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngrunwald%2Fmeta-csv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ngrunwald","download_url":"https://codeload.github.com/ngrunwald/meta-csv/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngrunwald%2Fmeta-csv/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29771041,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-24T04:01:02.180Z","status":"ssl_error","status_checked_at":"2026-02-24T03:59:49.901Z","response_time":75,"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":["csv","data-analysis"],"created_at":"2025-10-21T22:48:09.437Z","updated_at":"2026-02-24T04:02:25.742Z","avatar_url":"https://github.com/ngrunwald.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# meta-csv\n\nA smart reader for CSV files, spiritual successor to [ultra-csv](https://github.com/ngrunwald/ultra-csv).\n\n## Features\n\n  - Smart statistical heuristics to guess pretty much anything about\n  your csv file, from delimiter to quotes and whether a header is present\n  - Handles for you the boring but dangerous stuff, like encoding detection\n  and bom skipping if present, but also embedded new lines and quote escaping\n  - Coerces the numerical values that have been recognised. The types and\n  coercions can be extended by the user to *dates*, *phone numbers*, etc.\n  - Designed to be both very easy to use in an exploratory way to get a quick\n  feel for the data, and then be put into production with almost the same code\n\n## Installation\n\n`meta-csv` is available as a Maven artifact from\n[Clojars](http://clojars.org/meta-csv):\n\nIn your `project.clj` dependencies for *leiningen*:\n\n[![Clojars Project](http://clojars.org/meta-csv/latest-version.svg)](http://clojars.org/meta-csv)\n\n## Usage\n\nThe easiest way to use when hacking at the REPL is simply:\n\n```clojure\n(require '[meta-csv.core :as csv])\n```\n\n```clojure\n(first (csv/read-csv \"./dev-resources/samples/marine-economy-2007-18.csv\"))\n\n=\u003e {:year 2007,\n    :category \"Fisheries and aquaculture\",\n    :variable \"Cont. to ME Wage and salary earners\",\n    :units \"Proportion\",\n    :magnitude \"Actual\",\n    :source \"LEED\",\n    :data_value 43.1,\n    :flag \"R\"}\n```\n\nIf the file has a header, this returns a lazy seq of maps of field names to values.\n\nIf any field name would be problematic as keyword, then all field names will be\nstrings instead:\n\n```clojure\n(first (csv/read-csv \"./dev-resources/samples/sales-records-sample.csv\"))\n\n=\u003e {\"Region\" \"Australia and Oceania\",\n    \"Country\" \"Tuvalu\",\n    \"Item Type\" \"Baby Food\",\n    \"Sales Channel\" \"Offline\",\n    \"Order Priority\" \"H\",\n    \"Order Date\" \"5/28/2010\",\n    \"Order ID\" 669165933,\n    \"Ship Date\" \"6/27/2010\",\n    \"Units Sold\" 9925,\n    \"Unit Price\" 255.28,\n    \"Unit Cost\" 159.42,\n    \"Total Revenue\" 2533654.0,\n    \"Total Cost\" 1582243.5,\n    \"Total Profit\" 951410.5}\n```\n\nThe maps are array-maps, which means the order of the keys is the same as the\norder of the fields in the file.\n\nIf no header is present, the rows will be returned as a seq of vectors, in the same fashion as [clojure.data.csv/read-csv](https://clojure.github.io/data.csv/#clojure.data.csv/read-csv).\n\nA lot of options are available, as an optional second argument spec. Check the\ndocstring for a more or less exhaustive description.\n\nThis spec can actually be created by another noteworthy function, `guess-spec`.\n\n```clojure\n(csv/guess-spec \"./dev-resources/samples/marine-economy-2007-18.csv\")\n\n=\u003e {:fields\n    [{:field :year, :type :long}\n     {:field :category, :type :string}\n     {:field :variable, :type :string}\n     {:field :units, :type :string}\n     {:field :magnitude, :type :string}\n     {:field :source, :type :string}\n     {:field :data_value, :type :double}\n     {:field :flag, :type :string}],\n    :delimiter \\,,\n    :bom :none,\n    :encoding \"ISO-8859-1\",\n    :skip-analysis? true,\n    :header? true,\n    :quoted? false}\n```\n\nThen the `:fields` vector describing the processing on each field can be\ncustomized to produce exactly the right format of data. This spec can be used\ndirectly as the second argument to `read-csv`.\n\nThe useful functions are extensively documented in the docstrings of the [API\nDocumentation](https://cljdoc.org/d/meta-csv/meta-csv/CURRENT/doc/readme).\n\n[![cljdoc badge](https://cljdoc.org/badge/meta-csv/meta-csv)](https://cljdoc.org/d/meta-csv/meta-csv/CURRENT)\n\nThe test file also contains interesting examples.\n\n## Tips and tricks\n\nNeed to get out put as an array like clojure.data.csv but with type coercions?\nThe `:skip` param skips the first line and the false `:header?` returns arrays.\n\n```clojure\n(first (csv/read-csv \"./dev-resources/samples/marine-economy-2007-18.csv\" {:skip 1 :header? false}))\n\n=\u003e [2007\n    \"Fisheries and aquaculture\"\n    \"Cont. to ME Wage and salary earners\"\n    \"Proportion\"\n    \"Actual\"\n    \"LEED\"\n    43.1\n    \"R\"]\n```\n\nOne of the differences with [ultra-csv](https://github.com/ngrunwald/ultra-csv)\nis that meta-csv makes no attempt at validating output data. Validation is an\nimportant concern but should not be handled by the file format parser, even a\nsmart one. I recommend however in production using something like\n[spec-provider](https://github.com/stathissideris/spec-provider) to generate\nspecs and validating the data with them when they come from a manual source.\n\nIn the same spirit, I tend to use `read-csv` at the REPL when doing analysis\nwork, but when and if going to production, I generate a spec with `guess-spec`\nand uses that with `read-csv`, to make the process more reliable if the input\nfile format presents problems at a future time.\n\n## License\n\nCopyright © 2019-2020 Nils Grunwald\n\nThis program and the accompanying materials are made available under the\nterms of the Eclipse Public License 2.0 which is available at\nhttp://www.eclipse.org/legal/epl-2.0.\n\nThis Source Code may also be made available under the following Secondary\nLicenses when the conditions for such availability set forth in the Eclipse\nPublic License, v. 2.0 are satisfied: GNU General Public License as published by\nthe Free Software Foundation, either version 2 of the License, or (at your\noption) any later version, with the GNU Classpath Exception which is available\nat https://www.gnu.org/software/classpath/license.html.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngrunwald%2Fmeta-csv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fngrunwald%2Fmeta-csv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngrunwald%2Fmeta-csv/lists"}