{"id":13442552,"url":"https://github.com/40ants/teddy","last_synced_at":"2026-01-16T20:21:45.254Z","repository":{"id":143093004,"uuid":"272270042","full_name":"40ants/teddy","owner":"40ants","description":"A data framework for Common Lisp","archived":false,"fork":false,"pushed_at":"2024-03-23T11:08:04.000Z","size":543,"stargazers_count":92,"open_issues_count":2,"forks_count":2,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-10-28T05:59:21.409Z","etag":null,"topics":["common-lisp","data-structures","data-visualization","pandas"],"latest_commit_sha":null,"homepage":"http://40ants.com/teddy/","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/40ants.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-06-14T19:31:49.000Z","updated_at":"2024-05-31T21:36:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"ebedcf91-3b06-439b-849a-e128c5526b9a","html_url":"https://github.com/40ants/teddy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/40ants%2Fteddy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/40ants%2Fteddy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/40ants%2Fteddy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/40ants%2Fteddy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/40ants","download_url":"https://codeload.github.com/40ants/teddy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244630164,"owners_count":20484327,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["common-lisp","data-structures","data-visualization","pandas"],"created_at":"2024-07-31T03:01:47.162Z","updated_at":"2026-01-16T20:21:45.242Z","avatar_url":"https://github.com/40ants.png","language":"Common Lisp","funding_links":[],"categories":["Common Lisp"],"sub_categories":[],"readme":"I want you to meet Teddy. Teddy wanna be like pandas. Pandas are cool. Teddy want be cool too!\n\n![](teddy-bear.png)\n![](docs/teddy-bear.png)\n\n# Reasoning\n\nThis library provides some Common Lisp facitilies to work with data frames.\n\nCommon Lisp already has [numcl](https://github.com/numcl/numcl) to operate on arrays, and now we need\na more abstract tool to work with data like data sheets.\n\nTeddy make it possible to define a dataframe full of data, to slice it in different ways, to join data frames\nand see some statistics about the data.\n\nThis is a proof of the concept and API will be changed. Check the\n[ChangeLog.md](ChangeLog.md) to learn about new abilities and refactoring details.\n\n# How to create a data-frame\n\nHere is how we can create a simple data-frame:\n\n```lisp\nPOFTHEDAY\u003e (teddy/data-frame:make-data-frame\n            '(\"Idx\" \"Integers\" \"Uniform floats\" \"Gaussian\")\n            :rows\n            (loop repeat 10\n                  for idx upfrom 0\n                  collect (list idx\n                                (random 100)\n                                (random 1.0)\n                                (statistics:random-normal\n                                 :mean 5.0\n                                 :sd 0.2))))\n+-----+----------+----------------+----------+\n| Idx | Integers | Uniform floats | Gaussian |\n+-----+----------+----------------+----------+\n|   0 |       41 |           0.27 |   4.89d0 |\n|   1 |       98 |           0.08 |   4.93d0 |\n|   2 |        8 |           0.45 |   5.15d0 |\n|   3 |       56 |           0.63 |   4.87d0 |\n|   4 |       79 |           0.42 |   4.72d0 |\n|   5 |       19 |           0.04 |   4.73d0 |\n|   6 |        1 |           0.34 |   4.93d0 |\n|   7 |       79 |           0.60 |   5.25d0 |\n|   8 |       42 |           0.08 |   5.10d0 |\n|   9 |        7 |           0.86 |   5.31d0 |\n+-----+----------+----------------+----------+\n```\n\n# Data manipulation\n\nNow we can slice it by columns, rows or both:\n\n```lisp\nPOFTHEDAY\u003e (teddy/data-frame:head *d* 2)\n+-----+----------+----------------+----------+\n| Idx | Integers | Uniform floats | Gaussian |\n+-----+----------+----------------+----------+\n|   0 |       41 |           0.27 |   4.89d0 |\n|   1 |       98 |           0.08 |   4.93d0 |\n+-----+----------+----------------+----------+\nPOFTHEDAY\u003e (teddy/data-frame:tail *d* 2)\n+-----+----------+----------------+----------+\n| Idx | Integers | Uniform floats | Gaussian |\n+-----+----------+----------------+----------+\n|   8 |       42 |           0.08 |   5.10d0 |\n|   9 |        7 |           0.86 |   5.31d0 |\n+-----+----------+----------------+----------+\nPOFTHEDAY\u003e (teddy/data-frame:slice\n            *d*\n            :columns '(\"idx\" \"gaussian\"))\n+-----+----------+\n| Idx | Gaussian |\n+-----+----------+\n|   0 |   4.89d0 |\n|   1 |   4.93d0 |\n|   2 |   5.15d0 |\n|   3 |   4.87d0 |\n|   4 |   4.72d0 |\n|   5 |   4.73d0 |\n|   6 |   4.93d0 |\n|   7 |   5.25d0 |\n|   8 |   5.10d0 |\n|   9 |   5.31d0 |\n+-----+----------+\nPOFTHEDAY\u003e (teddy/data-frame:slice *d*\n            :columns '(\"idx\" \"gaussian\")\n            :from 4\n            :to 6)\n+-----+----------+\n| Idx | Gaussian |\n+-----+----------+\n|   4 |   4.72d0 |\n|   5 |   4.73d0 |\n+-----+----------+\n```\n\n# Analyzing data\n\nAlso, we might want to see some descriptive statistical data about our\ndata frame. This is pretty easy with Teddy:\n\n```lisp\nPOFTHEDAY\u003e (teddy/stats:stats *d*)\n+----------------+--------+--------+--------+--------+--------+-------+-------+---------+\n| Column         | Min    | p25    | p50    | p75    | Max    | Mean  | SD    | Sum     |\n+----------------+--------+--------+--------+--------+--------+-------+-------+---------+\n| Idx            |      0 |      2 |   4.50 |      7 |      9 |  4.50 |  3.03 |      45 |\n| Integers       |      1 |      8 |  41.50 |     79 |     98 | 43.00 | 34.40 |     430 |\n| Uniform floats |   0.04 |   0.08 |   0.38 |   0.60 |   0.86 |  0.38 |  0.27 |    3.75 |\n| Gaussian       | 4.72d0 | 4.87d0 | 4.93d0 | 5.15d0 | 5.31d0 |  4.99 |  0.20 | 49.88d0 |\n+----------------+--------+--------+--------+--------+--------+-------+-------+---------+\n```\n\nProbably, we can make some extandable protocol to calculate other\nproperties.\n\n# Iteration over rows\n\nData frame stores data as columns. Each column is a vector of particular\ntype. If you want to process a row, you can create an iterator and use\nit to go through rows like that:\n\n```lisp\nPOFTHEDAY\u003e (loop with iterator = (teddy/data-frame:make-iterator *d*)\n                 for row = (funcall iterator)\n                 while row\n                 do (format t \"Row: ~S~%\"\n                            row))\nRow: (0 41 0.26806116 4.887522971759381d0)\nRow: (1 98 0.081421256 4.928584134866222d0)\nRow: (2 8 0.45165908 5.147222819038834d0)\nRow: (3 56 0.62647486 4.874349648519968d0)\nRow: (4 79 0.41671002 4.7239718274963485d0)\nRow: (5 19 0.04152584 4.727268395019779d0)\nRow: (6 1 0.3369373 4.93339303609316d0)\nRow: (7 79 0.59791017 5.2466443304900965d0)\nRow: (8 42 0.076958776 5.103448455243024d0)\nRow: (9 7 0.85732913 5.310498824093041d0)\n\n```\n\n# Plotting data\n\nPlotting facilities as rudimentary. All functions related to plotting\nare in the `teddy/plot` package. Right now `GNUPlot` is used via\n[eazy-gnuplot](http://quickdocs.org/eazy-gnuplot/) library.\n\nHere is how we can plot our data from all columns:\n\n```lisp\n\nPOFTHEDAY\u003e (teddy/plot:plot *d*\n            \"docs/media/0099/simple-plot.png\")\n```\n\n![](simple-plot.png)\n![](docs/simple-plot.png)\n\nIf we want to plot only gaussian, then it will be wrong, because we need\nhistogram type of plot. This it \"to be done\":\n\n```lisp\nPOFTHEDAY\u003e (teddy/plot:plot\n            (teddy/data-frame:slice *d*\n                                    :columns '(\"Idx\" \"Gaussian\"))\n            \"docs/media/0099/gaussian.png\")\n```\n\n![](gaussian.png)\n![](docs/gaussian.png)\n\nAnother type of plots `Teddy` is able to render right now is a\n\"timeseries\":\n\n```lisp\n\nPOFTHEDAY\u003e (defparameter *moscow-population*\n             (teddy/data-frame:make-data-frame\n              '(\"Date\" \"Population\")\n              :rows '((\"1350-01-01\" 30000)\n                      (\"1840-01-01\" 349000)\n                      (\"1907-01-01\" 1345700)\n                      (\"1967-01-01\" 6422000)\n                      (\"1994-01-01\" 9066000)\n                      (\"2010-01-01\" 11500000)\n                      (\"2020-01-01\" 12680000))))\n*MOSCOW-POPULATION*\nPOFTHEDAY\u003e (teddy/plot:plot-timeseries\n            *moscow-population* \"docs/media/0099/moscow2.png\"\n            :title \"Moscow population\")\n\"docs/media/0099/moscow.png\"\n```\n\n![](moscow.png)\n![](docs/moscow.png)\n\nJoin the effort to make Teddy really useful for data analysis!\n\nRight now, Teddy installable only from Ultralisp, because it is the best\nplace to host unstable fast changing Common Lisp libraries.\n\n\n\n# Credentials\n\n* Logo is by [JenDigitalArt](https://pixabay.com/users/jendigitalart-6490932/?tab=about), was downloaded [from Pixabay](https://pixabay.com/illustrations/bear-cute-bear-cartoon-adorable-3189349/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F40ants%2Fteddy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F40ants%2Fteddy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F40ants%2Fteddy/lists"}