If you need to pass variables, you would indeed need to use dbutils.notebook.run() instead of %run.
As far as I'm aware, you can't rerun things between notebook executions. If you need to return a dataframe, the easiest solution seems to create this as a table within unity catalog, and fetch it later when you need it?
Databricks is not really ment for passing dataframes within notebooks - more create a notebook that runs setup, functions, filtering etc. and create a table, which you can then easily import and use later. That way you also get easier tracability, clarity and seperation of code, which is easier to maintain in the long run.