# => ╭────────────────┬───────────────────────────────────────────────────────╮
# => │ plan │ DF ["a", "b"]; PROJECT */2 COLUMNS; SELECTION: "None" │
# => │ optimized_plan │ DF ["a", "b"]; PROJECT */2 COLUMNS; SELECTION: "None" │
# => ╰────────────────┴───────────────────────────────────────────────────────╯
```
As you can see, the resulting dataframe is not yet evaluated, it stays as a
set of instructions that can be done on the data. If you were to collect that
dataframe you would get the next result
```nu
$lf_0 | polars collect
# => ╭───┬───┬───╮
# => │ # │ a │ b │
# => ├───┼───┼───┤
# => │ 0 │ 1 │ a │
# => │ 1 │ 2 │ b │
# => │ 2 │ 3 │ c │
# => │ 3 │ 4 │ d │
# => ╰───┴───┴───╯
```
as you can see, the collect command executes the plan and creates a nushell
table for you.
All dataframes operations should work with eager or lazy dataframes. They are
converted in the background for compatibility. However, to take advantage of
lazy operations if is recommended to only use lazy operations with lazy
dataframes.
To find all lazy dataframe operations you can use
```nu no-run
scope commands | where category =~ lazyframe | select name category usage
```
With your lazy frame defined we can start chaining operations on it. For
example this
```nu
$lf_0
| polars reverse
| polars with-column [
((polars col a) * 2 | polars as double_a)
((polars col a) / 2 | polars as half_a)
]
| polars collect
# => ╭───┬───┬───┬──────────┬────────╮
# => │ # │ a │ b │ double_a │ half_a │
# => ├───┼───┼───┼──────────┼────────┤
# => │ 0 │ 4 │ d │ 8 │ 2 │
# => │ 1 │ 3 │ c │ 6 │ 1 │
# => │ 2 │ 2 │ b │ 4 │ 1 │
# => │ 3 │ 1 │ a │ 2 │ 0 │
# => ╰───┴───┴───┴──────────┴────────╯
```
:::tip
You can use the line buffer editor to format your queries (`ctr + o`) easily
:::
This query uses the lazy reverse command to invert the dataframe and the
`polars with-column` command to create new two columns using `expressions`.
An `expression` is used to define an operation that is executed on the lazy
frame. When put together they create the whole set of instructions used by the
lazy commands to query the data. To list all the commands that generate an
expression you can use
```nu no-run
scope commands | where category =~ expression | select name category usage
```
In our previous example, we use the `polars col` command to indicate that column `a`
will be multiplied by 2 and then it will be aliased to the name `double_a`.
In some cases the use of the `polars col` command can be inferred. For example,
using the `polars select` command we can use only a string
```nu
$lf_0 | polars select a | polars collect
# => ╭───┬───╮
# => │ # │ a │
# => ├───┼───┤
# => │ 0 │ 1 │
# => │ 1 │ 2 │
# => │ 2 │ 3 │
# => │ 3 │ 4 │
# => ╰───┴───╯
```
or the `polars col` command
```nu
$lf_0 | polars select (polars col a) | polars collect
# => ╭───┬───╮
# => │ # │ a │
# => ├───┼───┤
# => │ 0 │ 1 │
# => │ 1 │ 2 │
# => │ 2 │ 3 │
# => │ 3 │ 4 │
# => ╰───┴───╯
```
Let's try something more complicated and create aggregations from a lazy
dataframe
```nu
let lf_1 = [[name value]; [one 1] [two 2] [one 1] [two 3]] | polars into-lazy
$lf_1
| polars group-by name
| polars agg [
(polars col value | polars sum | polars as sum)
(polars col value | polars mean | polars as mean)
]
| polars collect
# => ╭───┬──────┬─────┬──────╮
# => │ # │ name │ sum │ mean │
# => ├───┼──────┼─────┼──────┤
# => │ 0 │ two │ 5 │ 2.50 │
# => │ 1 │ one │ 2 │ 1.00 │
# => ╰───┴──────┴─────┴──────╯
```
And we could join on a lazy dataframe that hasn't being collected. Let's join
the resulting group by to the original lazy frame
```nu
let lf_2 = [[name value]; [one 1] [two 2] [one 1] [two 3]] | polars into-lazy
let group = $lf_2
| polars group-by name
| polars agg [
(polars col value | polars sum | polars as sum)
(polars col value | polars mean | polars as mean)
]
$lf_2 | polars join $group name name | polars collect