Data_editor - calculating rows and first class documentation

I’m looking to do something in data_editor which has proved challenging, but seems like a simple use-case. Basically, the dataframe I load into the data_editor has some rows that are raw values and some rows that are calculated off of other rows. When I have a user update the data_editor, I would like the calculating rows to update.

What I tried and couldn’t get to work:

  • Comparing the user’s updated df to the original df after the data_editor call and then recalculating any changes. This doesn’t work since the page re-runs before this recalculating occurs, so the df is unchanged in the data_editor.
  • Using a callback (on_change) to update the calculations or using the callback to save session_state’s so the new numbers can be used in the calculations. The callback doesn’t seem to have access to the updated df, so that wouldn’t work.
  • Assigning the st.data_editor to a session state (for example: st.session_state.df = st.date_editor(…)) and then prior to the original calculation, checking for whether this session state existed and using it’s values if so. This didn’t seem to assign the session state until after the re-run, so this didn’t calculate new values.

The only thing that finally worked was trying my first method, but then adding a st.experimental_rerun() at the end, so that it could pick up the changes before recalculating. However, this seems pretty inefficient since making changes to data_editor causes the page to re-run already, so the page is now re-running twice.

Having rows that calculate off other rows is very common in pandas dataframes and in places like excel, so it seems like that is a use-case that should be supported.

While looking into this, it became obvious that it would be helpful to have a first class set of documentation on how to use data_editor in a webapp with typical use-cases. Although we have docs here, those just say what the widget literally does and uses the data_editor output in a very basic way.

I also saw others having confusion on similar topics, with slightly different use-cases here and here, so it seems like others could benefit from this too.