---
# System prepended metadata

title: Tables Functions Documentation
tags: [Documentation]

---

---
tags: Documentation
title: Tables Functions Documentation -- pre-2023
---

<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 -- pre-2023

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 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. Here is an example "predicate" function (the input named `keep` for filter-with):
    
  ```
  fun age-under-fifteen(r :: Row) -> Boolean:
    doc: "returns true if the Number in row r, column 'age' is less than 15"
    r["age"] < 15
  end
  ```
    
    ![Input: filter-with(my-table, age-under-fifteen)
    Output: a table,
    name	age	favorite-color
    "Bob"	12	"blue"
    "Eve"	13	"red"](https://imgur.com/tn27jmt.png)
  
:::    success
***New for 2023:*** Using a lambda expression, the above example would look like:
`filter-with(my-table, lam(r): age-under-fifteen(r) end)`
or simply:
`filter-with(my-table, lam(r): r["age"] < 15 end)`
:::

<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` function returns.

* **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:
    ```
    fun is-teenager-builder(r :: Row) -> Boolean:
      doc: "returns true if the Number in row r, column 'age' is > 12 and < 20"
      r["age"] > 12 and r["age"] < 20
    end
    ```
    ![Input: build-column(my-table, "is-teenager", is-teenager-builder)
    Output: a table,
    "](https://imgur.com/CbAuGXK.png)

:::    success
***New for 2023:*** Using a lambda expression, the above example would look like:
`build-column(my-table, "is-teenager", lam(r): is-teenager-builder(r) end)`
or simply:
`build-column(my-table, "is-teenager", lam(r): (r["age"] > 12) and (r["age"] < 20) end)`
:::

<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&lt;A&gt;</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&lt;A&gt;</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)
