Search code examples
c#dataframedeedle

Convert Deedle data frame to an HTML table


I'm trying to convert a Deedle data frame into an HTML table. I can do it by first converting a Data Frame into C# DataTable, but I would like to do it directly. I've tried this code:

 internal static string ConvertDeedleFrameToHTML(Frame<int, string> df, string classtype, string title)
 {
     if (df.RowCount == 0) {
         return "<p">There are no results that satisfy the condition</p>";
     }
     string html = "<table border =\"1\" >";
     html += "<caption>" + title + "</caption>";
     //add header row
     html += "<tr class ='warning'>";
     for (int i = 0; i < df.ColumnCount; i++)
         html += "<td>" + df.Columns.GetKeyAt(i) + "</td>";
     html += "</tr>";
     String temp = " ";
     //add rows
     for (int i = 0; i < df.RowCount; i++)
     {
         html += "<tr>";
         for (int j = 0; j < df.ColumnCount; j++)
         {
             temp = df.GetRowAt<string>(i).Where(row => row.Key == df.Columns.GetKeyAt(j)).Observations.First().Value.ToString();
             //  temp = df.GetRowAt<int>(i).GetAt(j);
             //   temp2 = df.GetFrameData();
             html += "<td>" + temp + "</td>";
         }
         // df.GetColumnAt<int>(i);
         html += "</tr>";
     }
     html += "</table>";
     return html;
 }

It throws Object must implement IConvertible. error, when there are columns with type DateTime. However, it works when the columns are just strings and ints.

UPDATE: instead of a for loop, I am using a foreach statement:

foreach (var row in df.Rows.ObservationsAll) {
         html += "<tr border =\"1\">";
         for (int j = 0; j < df.ColumnCount; j++)
         {
             if (row.Value.Value.GetAt(j) != null)
             {
                 temp = row.Value.Value.GetAt(j).ToString();
             }
          //   temp = row.Value.Value.GetAt(j).ToString() ?? " ";
             html += "<td>" + temp + "</td>";
         }
         html += "</tr>";
     }

but it gives an error: OptionalValue.Value: Value is not available, when there is a null value


Solution

  • There is some code to do this (although in F#) in the FsLab Journal source code.

    The two key things that it does that are different than your sample:

    • It uses df.Rows to iterate over the rows. This gives you each row as Series<K, obj> where the string is the column key and obj is boxed value in the frame

    • Then it uses Series.observationsAll to get a sequence of key value pairs. In C#, you can use series.ObservationsAll to get a sequence of KeyValuePair<K, OptionalValue<obj>>, which gives you key, together with (possibly missing) boxed value.

    Using these two, you should be able to iterate over everything and format the frame as you need.