---
tags: Documentation
title: Tables Functions Documentation
---
<style type="text/css">
<-- Colton Rusch, Fall 2020 -->
@import url('https://fonts.googleapis.com/css2?family=Fira+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap');
.pyret-text {
font-family: 'Source Code Pro', monospace;
font-size: 15px;
border-top: 1px solid #99b;
margin: 0;
margin-top: 1em;
margin-bottom: 1em;
padding: 0.25em;
padding-top: 0.3em;
padding-bottom: 0.4em;
background: linear-gradient(to bottom left, hsl(0, 0%, 99%) 0%, hsl(216, 62%, 95%) 100%);
}
</style>
# Tables Functions Documentation
Pyret has three different notations for manipulating Tables (each makes sense for someone starting Tables with a different goal or prior knowledge about programming). The version we are using, based on functions, is not covered in the Pyret documentation, but it is in the [textbook](https://dcic-world.org). This page summarizes the functions you can use to manipulate Tables.
:::info
Use this, not the Pyret Documentation, for working with Tables!
:::
Always start by including these functions at the top of your file!
```
include shared-gdrive("dcic-2021", "1wyQZj_L0qqV9Ekgr9au6RX2iqt2Ga8Ep")
```
:::info
Many of the examples given for the functions described below will be using the Table called `my-table` created in the section below, ["Creating a Table from Scratch."](#Creating-a-Table-from-Scratch)
:::
---
## Creating a Table from Scratch
If we want to explicitly define a `Table`, we can write it using this syntax:
```
table: col0-name :: col0-type, col1-name :: col1-type, ...
row: r0c0, r0c1, ...
row: r1c0, r1c1, ...
row: r2c0, r2c1, ...
...
end
```
* **Example:**
```
my-table = table: name :: String, age :: Number, favorite-color :: String
row: "Bob", 12, "blue"
row: "Alice", 17, "green"
row: "Eve", 13, "red"
end
```
Evaluating `my-table` in the interactions window after running the program above will display a formatted version of the `Table`:
![table example](https://www.pyret.org/docs/latest/table-print.png)
---
## Accessing a Row or Value in a Table
**Getting a row**: To get a specific row number from the table, use `row-n` from the standard Pyret documentation.
* **Example:**
```>>> my-table.row-n(0)```
**Getting a value**: The syntax `my-row[col-name]` accesses a `Row` at a particular column, resulting in a particular value. e.g. `my-row["age"]`→`20`.
To get a particular value in a `Table`, put these two together, e.g. `my-table.row-n(0)["age"]` would retrieve the value for the column "age" in the first row of the `Table`.
* **Example:**
```
>>> my-table.row-n(0)["age"]
12
```
```
>>> alice-row = my-table.row-n(1)
>>> alice-row["favorite-color"]
"green"
```
---
## Creating and Extracting Tables
<div id="filter-with" class="pyret-text"><b>filter-with</b>(t :: Table, keep :: (Row -> Boolean)) -> Table</div>
Given a `Table` and a predicate (e.g. lambda expression) on rows, returns a `Table` with only the rows for which the predicate returns `true`.
* **Example:**
Suppose we wanted to keep only rows of `my-table` that have an "age" value less than 15. We would write the expression:
```
filter-with(my-table, lam(r): r["age"] < 15 end)
```
![Output: a table,
name age favorite-color
"Bob" 12 "blue"
"Eve" 13 "red"](https://hackmd.io/_uploads/BylzYuDyT.png)
<div id="order-by" class="pyret-text"><b>order-by</b>(t :: Table, colname :: String, sort-up :: Boolean) -> Table</div>
Given a `Table` and the name of a column in that `Table`, return a `Table` with the same rows ordered based on the named column. If `sort-up` is `true`, the `Table` will be sorted in ascending order, otherwise it will be in descending order.
* **Examples:**
![Input: order-by(my-table, "age", true)
Output: a table,
name age favorite-color
"Bob" 12 "blue"
"Eve" 13 "red"
"Alice" 17 "green"](https://i.imgur.com/CghsqzE.png)
![Input: order-by(my-table, "name", false)
Output: a table,
name age favorite-color
"Eve" 13 "red"
"Bob" 12 "blue"
"Alice" 17 "green"](https://i.imgur.com/ZcqfgvF.png)
<div id="build-column" class="pyret-text"><b>build-column</b>(t :: Table, colname :: String, builder :: (Row -> A)) -> Table</div>
Consumes an existing `Table` and produces a new `Table` containing an additional column with the given `colname`, using `builder` to produce the values for that column, once for each row.
Here, `A` is the type of the new column, determined by the type of value the `builder` predicate produces.
* **Example:**
Suppose we wanted to create a column that tells us whether or not the value in each `Row`'s "age" column is in the 'teens' (i.e. thir*teen* to nine*teen*). Here is an example `builder` function:
```
build-column(my-table, "is-teenager", lam(r): (r["age"] > 12) and (r["age"] < 20) end)
```
![a table](https://hackmd.io/_uploads/Hk_3YuwyT.png)
<div id="add-row" class="pyret-text"><b>add-row</b>(t :: Table, r :: Row) -> Table</div>
Consumes a `Table` and a `Row` to add, and produces a new `Table` with the rows from the original table followed by the given `Row`.
* **Example:**
Suppose we have this other table, inspiringly named `other-table`, and we want to add its second `Row` to our original table, `my-table`:
```
other-table = table: name :: String, age :: Number, favorite-color :: String
row: "Julia", 21, "marigold"
row: "Colton", 19, "blue"
row: "Monica", 20, "purple"
row: "Giselle", 21, "red"
end
```
![Input: new-row = get-row(other-table, 1)
add-row(my-table, new-row)
Output: a table,
name age favorite-color
"Bob" 12 "blue"
"Alice" 17 "green"
"Eve" 13 "red"
"Colton" 19 "blue"](https://imgur.com/DgjpKE9.png)
(*note: the get-row expression in the figure should be `other-table.row-n(1)`*)
<div id="add-col" class="pyret-text"><b>add-col</b>(t :: Table, colname :: String, c-vals :: List<Any>) -> Table</div>
Consumes a `String` representing a column name and a `List` of values and produces a new `Table` with the columns of the input `Table` followed by a column with the given name and values. Note that the length of `c-vals` must equal the length of the `Table`.
* **Example:**
Here's a `List<String>` representing hair colors, which we want to add to `my-table` as a column:
```
hair-color-c-vals = [list: "brown", "red", "blonde"]
```
![Input: add-col(my-table, "hair-color", hair-color-c-vals)
Output: a table,
name age favorite-color hair-color
"Bob" 12 "blue" "brown"
"Alice" 17 "green" "red"
"Eve" 13 "red" "blonde"](https://imgur.com/2kbZfoB.png)
<div id="select-columns" class="pyret-text"><b>select-columns</b>(t :: Table, colnames :: List<String>) -> Table</div>
Consumes a `Table` and a `List<String>` containing column names, and produces a new `Table` containing only those columns. The order of the columns is as given in the input `List`.
* **Example:**
```
desired-colnames = [list: "name", "favorite-color"]
```
![Input: select-columns(my-table, desired-colnames)
Output: a table,
name favorite-color
"Bob" "blue"
"Alice" "green"
"Eve" "red"](https://imgur.com/UJXenmg.png)
<div id="transform-column" class="pyret-text"><b>transform-column</b>(t :: Table, colname :: String, f :: (A -> B)) -> Table</div>
Consumes a `Table`, a `String` representing a column name, and a transformation function and produces a new `Table` where the transformation function has been applied to all values in the named column. The values in the original column are of type `A` (the input type of the function) and values in the new column have type `B` (the output type of the function).
* **Example:**
Suppose the rows of `my-table` represent a family whose last name is "Smith." We want to change each name in the "name" column to whatever `String` is currently in the column plus the `String` " Smith" after it.
Here is a transformation function for this example:
```
fun add-last-name(name :: String) -> String:
doc: "consumes a String; returns that String + ' Smith'"
name + ' Smith'
end
```
![Input: transform-column(my-table, "name", add-last-name)
Output: a table,
name age favorite-color
"Bob Smith" 12 "blue"
"Alice Smith" 17 "green"
"Eve Smith" 13 "red"](https://imgur.com/Vt4zu9M.png)
---
## Extracting Data Through Table Methods
Table methods are how we extract data from a table. Methods are similar in spirit to functions, but their notation (*table.operation(args)*) is more suggestive of going inside a table to extract data.
<!--***t.row-n**(n :: Number) -> Row*
For a table *t*, returns the *n*th row, where row numbers start at 0-->
<div id=".length" class="pyret-text"><b>t.length</b>() -> Number</div>
For the `Table` named `t`, returns a `Number` representing the number of rows in the `Table`.
* **Example:**
```
>>> my-table.length()
3
```
<div id=".get-column" class="pyret-text"><b>t.get-column</b>(colname :: String) -> List<A></div>
Returns a `List` of the values in the named column in the `Table` named `t`. `A` is the type of the data in the named column.
* **Example:**
```
>>> my-table.get-column("name")
[list: "Bob", "Alice", "Eve"]
```
<div id=".drop" class="pyret-text"><b>t.drop</b>(colname :: String) -> Table</div>
Returns a `Table` that is the same as `Table` `t`, except without the column whose name is `colname`.
* **Example:**
![Input: my-table.drop("age")
Output: a table,
name favorite-color
"Bob" "blue"
"Alice" "green"
"Eve" "red"](https://imgur.com/ZHbjjJI.png)
---
## Summarizing Columns
<div id="sum" class="pyret-text"><b>sum</b>(t :: Table, colname :: String) -> Number</div>
Takes a `Table` and a `String` representing the name of a column in that `Table`. Returns a `Number` representing the sum of the values in the column. Note that the given column must contain `Number` values.
* **Example:**
```
>>> sum(my-table, "age")
42
```
<div id="mean" class="pyret-text"><b>mean</b>(t :: Table, colname :: String) -> Number</div>
Takes a `Table` and a `String` representing the name of a column in that `Table`. Returns a `Number` representing the mean (average value) of values in the column. Note that the given column must contain `Number` values
* **Example:**
```
>>> mean(my-table, "age")
14
```
<div id="median" class="pyret-text"><b>median</b>(t :: Table, colname :: String) -> Number</div>
Takes a `Table` and a `String` representing the name of a column in that `Table`. Returns a `Number` representing the median (middle value) of values in the column. Note that the given column must contain `Number` values.
* **Example:**
```
>>> median(my-table, "age")
13
```
<div id="modes" class="pyret-text"><b>modes</b>(t :: Table, colname :: String) -> List<A></div>
Takes a `Table` and a `String` representing the name of a column in that `Table`. Returns a `List<Number>` containing the modes (most frequently occurring values) in the given column, where `A` is the type of data in the given column.
* **Examples:**
```
>>> modes(my-table, "age")
[list: ]
```
```
new-table = table: color :: String
row: "blue"
row: "blue"
row: "red"
end
```
```
>>> modes(new-table, "color")
[list: "blue"]
```
<div id="stdev" class="pyret-text"><b>stdev</b>(t :: Table, colname :: String) -> Number</div>
Takes a `Table` and a `String` representing the name of a column in that `Table`. Returns a `Number` representing the standard deviation (a measure of how spread out values are) of the values in the given column. Note that the given column must contain `Number` values.
:::warning
**Warning:** `stdev` produces `Roughnum` values (Pyret's way of representing approximations of irrational numbers), which may not work with some operations (for example, `order-by` cannot be called on a column containing `Roughnums`). You can convert a `Roughnum` to a rational number using [`num-to-rational`](https://www.pyret.org/docs/latest/numbers.html#%28part._numbers_num-to-rational%29).
:::
* **Example:**
```
>>> stdev(my-table, "age")
~2.160246899469287
```
<div id="count" class="pyret-text"><b>count</b>(tab :: Table, colname :: String) -> Table</div>
Takes a `Table` and a `String` representing the name of a column in that `Table`. Produces a `Table` that summarizes how many rows have each value in the given column.
* **Example:**
![Input: count(my-table, "age")
Output: a table,
value count
"Eve" 1
"Alice" 1
"Bob" 1](https://imgur.com/RGxWbPc.png)
---
## Plots and Charts
In this section, we'll use the following table of heights and weights, `height-weight-table` to illustrate many of the following plot and chart functions:
```
height-weight-table = table: height :: Number, weight :: Number
row: 74, 242
row: 69, 162
row: 74, 213
row: 72, 220
row: 70, 206
end
```
<div id="histogram" class="pyret-text"><b>histogram</b>(t :: Table, colname :: String, bin-width :: Number) -> Image</div>
Displays an `Image` of a histogram of values in the named column, which must contain numeric data. `bin-width` indicates the width of bins in the histogram.
* **Example:**
```
>>> histogram(height-weight-table, "height", 3)
```
![Input: histogram of heights from height-weight-table](https://imgur.com/mUUmL98.png)
<div id="scatter-plot" class="pyret-text"><b>scatter-plot</b>(t :: Table, xs :: String, ys :: String) -> Image</div>
Displays an `Image` of a scatter plot from the given table. `xs` names the column in `t` to use for x-values, and `ys` names the column in `t` to use for y-values. Both columns must contain `Number` values.
* **Example:**
```
>>> scatter-plot(height-weight-table, "height", "weight")
```
![Input: scatter plot of heights and weights from heights-weights-table](https://imgur.com/fVlNN7v.png)
<div id="lr-plot" class="pyret-text"><b>lr-plot</b>(t :: Table, xs :: String, ys :: String) -> Image</div>
Like a call to `scatter-plot` with the same inputs. The difference is that a linear regression will be attempted on the elements of the plot, and a regression line will the be drawn over the data.
* **Example:**
```
>>> lr-plot(height-weight-table, "height", "weight")
```
![Input: linear regression plot of heights and weights from heights-weights-table](https://imgur.com/qmdd0QF.png)
<div id="pie-chart" class="pyret-text"><b>pie-chart</b>(t :: Table, ls :: String, vs :: String) -> Image</div>
Display an `Image` of a pie-chart from the given `Table` (one slice per row). `ls` is the label to use for the chart, and `vs` names the column of the `Table` to use for values in the pie chart.
* **Example:**
```
cs111-syllabus-table = table: course-component :: String, grade-weight :: Number
row: "Drills/Lecture Activities", 10
row: "Labs", 10
row: "Homeworks", 25
row: "Projects", 25
row: "Code Check-ins", 15
row: "Exams", 15
end
```
```
>>> pie-chart(cs111-syllabus-table, "course-component", "grade-weight")
```
![Input: pie chart of grade weights from cs111-syllabus-table](https://imgur.com/15HO1sr.png)
<div id="bar-chart" class="pyret-text"><b>bar-chart</b>(t :: Table, ls :: String, vs :: String) -> Image</div>
Displays an `Image` of a bar-chart from the given `Table` (one bar per row). `ls` names the column of the `Table` to use for labels, and `vs` names the column of the `Table` to use for values in the bar chart.
* **Example:**
```
cs111-syllabus-table = table: course-component :: String, grade-weight :: Number
row: "Drills/Lecture Activities", 10
row: "Labs", 10
row: "Homeworks", 25
row: "Projects", 25
row: "Code Check-ins", 15
row: "Exams", 15
end
```
```
>>> bar-chart(cs111-syllabus-table, "course-component", "grade-weight")
```
![Input: bar chart of grade weights from cs111-syllabus-table](https://imgur.com/5zpuyxQ.png)
<div id="freq-bar-chart" class="pyret-text"><b>freq-bar-chart</b>(t :: Table, vs :: String) -> Image</div>
Display an `Image` of a frequency bar-chart from the given `Table`. There is one bar for each unique value of the column with name `vs` (showing the number of occurrences of that value).
* **Example:**
```
favorite-colors-table = table: color :: String
row: "blue"
row: "red"
row: "green"
row: "blue"
row: "blue"
row: "red"
end
```
```
>>> freq-bar-chart(favorite-colors-table, "color")
```
![Input: frequency bar chart of colors from favorite-colors-table](https://imgur.com/D8cuoUI.png)
<div id="box-plot" class="pyret-text"><b>box-plot</b>(t :: Table, vs :: String) -> Image</div>
Produces an `Image` of a box plot of the values in the column named `vs` in the `Table`. A box plot shows the minimum, maximum, and median values of a column, as well as the first (lowest) and third quartiles of the dataset; this is helpful for seeing the variation in a dataset.
* **Example:**
```
>>> box-plot(height-weight-table, "weight")
```
![Input: box plot of weights from heights-weights-table](https://imgur.com/aHkWSwT.png)