Rent dashboard
This page uses the simulated rentals data. It does not describe real rentals.
This example is a small reactive dashboard in the style of a Shiny app. Each input is a property of a Livewire component. When an input changes, the server filters the data with phplyr, summarises it, refits a logistic model with phit, and returns new tables and phiz charts. The page has no JavaScript written for it.
The model estimates the probability that a rental costs more than the budget from its floor area and number of bedrooms.
Code
class RentDashboard extends Component
{
public array $neighborhoods = [...];
public int $minBedrooms = 1;
public int $maxBedrooms = 4;
public int $budget = 2500;
public function render()
{
$rentals = DataFrame::fromQuery(SimulatedRental::query()) |>
filter(col('neighborhood')->isIn($this->neighborhoods),
col('bedrooms')->between($this->minBedrooms, $this->maxBedrooms)) |>
mutate(over_budget: col('monthly_rent')->gt($this->budget));
$summary = $rentals |>
group_by('neighborhood') |>
summarise(rentals: n(), median_rent: median('monthly_rent'),
share_over_budget: mean('over_budget'));
$model = $rentals |> glm('over_budget ~ area_m2 + bedrooms', family: 'binomial');
return view('livewire.rent-dashboard', compact('rentals', 'summary', 'model'));
}
}
class RentDashboard extends Component
{
public array $neighborhoods = [...];
public int $minBedrooms = 1;
public int $maxBedrooms = 4;
public int $budget = 2500;
public function render()
{
$rentals = phplyr(DataFrame::fromQuery(SimulatedRental::query()))
->filter(col('neighborhood')->isIn($this->neighborhoods),
col('bedrooms')->between($this->minBedrooms, $this->maxBedrooms))
->mutate(over_budget: col('monthly_rent')->gt($this->budget))
->get();
$summary = phplyr($rentals)
->groupBy('neighborhood')
->summarise(rentals: n(), median_rent: median('monthly_rent'),
share_over_budget: mean('over_budget'))
->get();
$model = phplyr($rentals)->glm('over_budget ~ area_m2 + bedrooms', family: 'binomial');
return view('livewire.rent-dashboard', compact('rentals', 'summary', 'model'));
}
}
<input type="checkbox" value="Harbor" wire:model.live="neighborhoods">
<x-phiz :plot="$scatter" />