Skip to content

Commit 80ee095

Browse files
committed
render.data_frame: change to iloc instead of loc
Instead of returning Pandas index values for selected rows, use 0-indexed row numbers instead. This is more likely to work with non-Pandas data frame libraries in the future, and also saves us from needing to try to serialize/deserialize arbitrary index types.
1 parent 1d20b47 commit 80ee095

File tree

7 files changed

+37
-29
lines changed

7 files changed

+37
-29
lines changed

e2e/bugs/0676-row-selection/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def detail():
3939
and len(input.grid_selected_rows()) > 0
4040
):
4141
# "split", "records", "index", "columns", "values", "table"
42-
return df.loc[list(input.grid_selected_rows())]
42+
return df.iloc[list(input.grid_selected_rows())]
4343

4444

4545
app = App(app_ui, server, debug=True)

js/dataframe/index.tsx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,6 @@ const ShinyDataGrid: FC<ShinyDataGridProps<unknown>> = (props) => {
6060
const { id, data, bgcolor } = props;
6161
const { columns, index, type_hints, data: rowData } = data;
6262
const { width, height, filters: withFilters } = data.options;
63-
// The terminology here is a bit confusing. The "key" is the `data-key` attribute on
64-
// the table>tbody>tr, which is populated by Tanstack table API's row id, which is
65-
// always [0, 1, 2, ...]. The "index" refers to the Pandas index coming from the
66-
// Python side, which may or may not be [0, 1, 2, ...]--it could be strings,
67-
// discontiguous numbers, or whatever. So the keyToIndex map lets you convert a
68-
// Tanstack row to the Pandas index.
69-
const keyToIndex: Record<string, unknown> = {};
70-
index.forEach((value, i) => {
71-
keyToIndex[i + ""] = value;
72-
});
7363

7464
const containerRef = useRef<HTMLDivElement>(null);
7565
const theadRef = useRef<HTMLTableSectionElement>(null);
@@ -198,7 +188,7 @@ const ShinyDataGrid: FC<ShinyDataGridProps<unknown>> = (props) => {
198188
rowSelection
199189
.keys()
200190
.toList()
201-
.map((key) => keyToIndex[key])
191+
.map((key) => parseInt(key))
202192
);
203193
}
204194
}

shiny/api-examples/data_frame/app.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ def summary_data():
6363

6464
@reactive.Calc
6565
def filtered_df():
66+
# input.summary_data_selected_rows() is a tuple, so we must convert it to list,
67+
# as that's what Pandas requires for indexing.
6668
selected_idx = list(req(input.summary_data_selected_rows()))
6769
countries = summary_df["country"][selected_idx]
6870
# Filter data for selected countries

shiny/render/_dataframe.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,29 +255,44 @@ def data_frame(
255255
_fn: DataFrameTransformer.ValueFn | None = None,
256256
) -> DataFrameTransformer.OutputRenderer | DataFrameTransformer.OutputRendererDecorator:
257257
"""
258-
Reactively render a Pandas data frame object (or similar) as a basic HTML table.
259-
258+
Reactively render a Pandas data frame object (or similar) as an interactive table or
259+
grid. Features fast virtualized scrolling, sorting, filtering, and row selection
260+
(single or multiple).
260261
261262
Returns
262263
-------
263264
:
264265
A decorator for a function that returns any of the following:
265266
266-
1. A pandas :class:`DataFrame` object.
267-
2. A pandas :class:`Styler` object.
267+
1. A :class:`~shiny.render.DataGrid` or :class:`~shiny.render.DataTable` object,
268+
which can be used to customize the appearance and behavior of the data frame
269+
output.
270+
2. A pandas :class:`DataFrame` object. (Equivalent to
271+
`shiny.render.DataGrid(df)`.)
268272
3. Any object that has a `.to_pandas()` method (e.g., a Polars data frame or
269-
Arrow table).
273+
Arrow table). (Equivalent to `shiny.render.DataGrid(df.to_pandas())`.)
274+
275+
Row selection
276+
-------------
277+
When using the row selection feature, you can access the selected rows by using the
278+
`input.<id>_selected_rows()` function, where `<id>` is the `id` of the
279+
:func:`~shiny.ui.output_data_frame`. The value returned will be `None` if no rows
280+
are selected, or a tuple of integers representing the indices of the selected rows.
281+
To filter a pandas data frame down to the selected rows, use
282+
`df.iloc[list(input.<id>_selected_rows())]`.
270283
271284
Tip
272285
----
273286
This decorator should be applied **before** the ``@output`` decorator. Also, the
274-
name of the decorated function (or ``@output(id=...)``) should match the ``id`` of
275-
a :func:`~shiny.ui.output_table` container (see :func:`~shiny.ui.output_table` for
287+
name of the decorated function (or ``@output(id=...)``) should match the ``id`` of a
288+
:func:`~shiny.ui.output_table` container (see :func:`~shiny.ui.output_table` for
276289
example usage).
277290
278291
See Also
279292
--------
280-
~shiny.ui.output_data_frame
293+
* :func:`~shiny.ui.output_data_frame`
294+
* :class:`~shiny.render.DataGrid` and :class:`~shiny.render.DataTable` are the
295+
objects you can return from the rendering function to specify options.
281296
"""
282297
return DataFrameTransformer(_fn)
283298

shiny/ui/dataframe/_dataframe.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ def data_frame_deps() -> HTMLDependency:
2323

2424
def output_data_frame(id: str) -> Tag:
2525
"""
26-
Create a output container for a data frame.
26+
Create an output container for an interactive table or grid. Features fast
27+
virtualized scrolling, sorting, filtering, and row selection (single or multiple).
2728
2829
Parameters
2930
----------
3031
id
31-
An input id.
32+
An output id.
3233
3334
Returns
3435
-------

shiny/www/shared/dataframe/dataframe.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

shiny/www/shared/dataframe/dataframe.js.map

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)