use crate::{Error, Result, TypeError, Value};
use polars::prelude::*;
pub fn unpivot(
value: &Value,
id_columns: &[String],
value_columns: &[String],
variable_name: &str,
value_name: &str,
) -> Result<Value> {
match value {
Value::DataFrame(df) => {
let mut unpivoted = if id_columns.is_empty() {
df.clone()
.unpivot([] as [&str; 0], value_columns)
.map_err(Error::from)?
} else {
df.clone()
.unpivot(id_columns, value_columns)
.map_err(Error::from)?
};
unpivoted
.rename("variable", variable_name.into())
.map_err(Error::from)?;
unpivoted
.rename("value", value_name.into())
.map_err(Error::from)?;
Ok(Value::DataFrame(unpivoted))
}
Value::LazyFrame(lf) => {
let df = lf.clone().collect().map_err(Error::from)?;
unpivot(
&Value::DataFrame(df),
id_columns,
value_columns,
variable_name,
value_name,
)
}
_ => Err(TypeError::UnsupportedOperation {
operation: "unpivot".to_string(),
typ: value.type_name().to_string(),
}
.into()),
}
}