diff --git a/docs/src/data-manipulation.md b/docs/src/data-manipulation.md index 34aa99c..bcb1b77 100644 --- a/docs/src/data-manipulation.md +++ b/docs/src/data-manipulation.md @@ -1,7 +1,8 @@ # Data Manipulation -RustFrame's `Frame` type couples tabular data with -column labels and a typed row index. +Rustframe's `Frame` type couples tabular data with +column labels and a typed row index. Frames expose a familiar API for loading +data, selecting rows or columns and performing aggregations. ## Creating a Frame @@ -17,27 +18,60 @@ assert_eq!(frame["A"], vec![1.0, 2.0]); ## Indexing Rows +Row labels can be integers, dates or a default range. Retrieving a row returns a +view that lets you inspect values by column name or position. + +```rust +# extern crate rustframe; +# extern crate chrono; +use chrono::NaiveDate; +use rustframe::frame::{Frame, RowIndex}; +use rustframe::matrix::Matrix; + +let d = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); +let data = Matrix::from_cols(vec![vec![1.0, 2.0], vec![3.0, 4.0]]); +let index = RowIndex::Date(vec![d(2024, 1, 1), d(2024, 1, 2)]); +let mut frame = Frame::new(data, vec!["A", "B"], Some(index)); +assert_eq!(frame.get_row_date(d(2024, 1, 2))["B"], 4.0); + +// mutate by row key +frame.get_row_date_mut(d(2024, 1, 1)).set_by_index(0, 9.0); +assert_eq!(frame.get_row_date(d(2024, 1, 1))["A"], 9.0); +``` + +## Column operations + +Columns can be inserted, renamed, removed or reordered in place. + ```rust # extern crate rustframe; use rustframe::frame::{Frame, RowIndex}; use rustframe::matrix::Matrix; -let data = Matrix::from_cols(vec![vec![1.0, 2.0], vec![3.0, 4.0]]); -let index = RowIndex::Int(vec![10, 20]); -let frame = Frame::new(data, vec!["A", "B"], Some(index)); -assert_eq!(frame.get_row(20)["B"], 4.0); +let data = Matrix::from_cols(vec![vec![1, 2], vec![3, 4]]); +let mut frame = Frame::new(data, vec!["X", "Y"], Some(RowIndex::Range(0..2))); + +frame.add_column("Z", vec![5, 6]); +frame.rename("Y", "W"); +let removed = frame.delete_column("X"); +assert_eq!(removed, vec![1, 2]); +frame.sort_columns(); +assert_eq!(frame.columns(), &["W", "Z"]); ``` ## Aggregations +Any numeric aggregation available on `Matrix` is forwarded to `Frame`. + ```rust # extern crate rustframe; use rustframe::frame::Frame; use rustframe::matrix::{Matrix, SeriesOps}; -let frame = Frame::new(Matrix::from_cols(vec![vec![1.0, 2.0]]), vec!["A"], None); -assert_eq!(frame.sum_vertical(), vec![3.0]); +let frame = Frame::new(Matrix::from_cols(vec![vec![1.0, 2.0], vec![3.0, 4.0]]), vec!["A", "B"], None); +assert_eq!(frame.sum_vertical(), vec![3.0, 7.0]); +assert_eq!(frame.sum_horizontal(), vec![4.0, 6.0]); ``` -When you're ready to run analytics, continue to the -[compute features](./compute.md) chapter. +With the basics covered, continue to the [compute features](./compute.md) +chapter for statistics and analytics.