Export table from Notebook

Hi,

I grew fond of Observable for data wrangling. I have a case where I load multiple tables as attachments, merge them together, do some curation and plots. And then I would like to export that again as TSV for download. Is there a way to do that? So similar to Downloading images, I’d like to download tables, for example from Data Table Cells.

Thanks.

There should be a “Download CSV” option in the table’s cell menu:

Hmm, not for me. Is that in the “Data Table Cell”? I don’t have that option, for some strange reason.

I believe I vaguely recall some limitations with regard to certain data types.

Are you able to share your notebook? If not, could you try the following:

  1. Give your table cell a name (e.g. “myTable”)
  2. Create a JS cell with the following content:
    myTable.schema.map(({type, inferred}) => `${type}:${inferred}`).join()
    
  3. Share the cell’s output here?

OK, first I should mention the fact that the table I’m viewing here is actually an arguero-table! It turns out that once I call myArqueroTable.objects(), and display that in the Data Table Cell, the CSV export button appears! So that’s already great!

Now, to your question about the schema: When I apply the recipe you propose on the table-output from the Data Table Cell viewing the arquero-table, I get:

"string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined,string:undefined"

When I do the same thing after first converting the arquero-table with .objects(), I get:

"string:string,string:string,string:string,string:string,string:string,number:number,number:number,string:string,integer:integer,integer:integer,integer:integer,number:number,number:number,number:number,integer:integer,number:number,boolean:boolean,string:string"

so now all these data types are known.

So indeed this may have been the problem, that the arquero-table somehow has bad datatypes associated with the columns. Not sure why that happens. As soon as I convert with objects(), it somehow magically turns the strings into proper types. Curious!

Nice detective work! Do you think you could create a public example notebook for us with a reduced dataset to demonstrate the problem?

1 Like

@stschiff If creating an example turns out to be too time consuming, could you instead describe the steps that allowed you to set an Arquero table object as data source for a Data Table cell?

The only way I can think of is if the cell contained an array when linked, and was later changed to return an Arquero table instead.

Edit: I see now that it’s only the “Insert cell after” option that doesn’t appear for the arquero cell, but that the cell can still be selected as data source and is even labeled “Arquero”.

1 Like

Sorry for taking some time here, I hoped that I can figure it out myself. I now put together a Notebook that shows the issue.

I think it’s not a huge problem, but there does seem to be some bug there. To summarize the symptom:

  • Javascript cells that resolve to a table in the form of a list of row-objects are usually downloadable as CSV and JSON using the Cell-context menu on the left.
  • Javascript cells that resolve to an arquero table do not come with a “Download as CSV or JSON” option. Fine.
  • But: When we use that arquero table (whether it’s typed or not) in a Data Table Cell, the output of that Data Table Cell is a simple list of objects, not an arquero table anymore. So it should be downloadable as CSV. But it isn’t.

Not sure whether that classifies as a bug. I would certainly call it surprising, if some list-of-object-tables are downloadable, and some ar not.

1 Like

I think it’s fair to call it a bug. Worth noting that the table’s value is an array of DuckDB Row objects, which is likely the underlying reason why the Download options aren’t available. We also don’t display the option to change column types or to add computed columns.

To restate the workaround (that you also mentioned): given an arquero Table object named myData, either call myData.objects(), or destructure the Table object via [...myData].

(For future reference, an example table can be created via aq.from(penguins).)

Ah yes, good observation, I didn’t even notice the fact that the output in this case are Row objects. And the workaround is indeed an easy one.

Thanks for bearing with me. Let me know if it would be useful if I submit an issue somewhere.

We’ve just fixed it. Let us know if it works for you?

Yes, wonderful. It works! Thanks!

1 Like