Search code examples
octave

Display Cell in a Table Form


I am wondering If it is possible to display Cell in a Table Form while using Octave. It would be easier for me to obtain information of the Cell. If it were displayed in a single column, I have to scroll down all the time.


Solution

  • The cell array default display looks kinda complicated:

    octave> a = {"foo", "bar", "qux"; "baz", "nof", "zot"}
    a = 
    {
      [1,1] = foo
      [2,1] = baz
      [1,2] = bar
      [2,2] = nof
      [1,3] = qux
      [2,3] = zot
    }
    

    It would be much nicer to see something such as:

    octave> a = {"foo", "bar", "qux"; "baz", "nof", "zot"}
    a(1:2, 1:3) = 
    {
      "foo"    "bar"    "qux"
      "baz"    "nof"    "zot"
    }
    

    However, a cell array can have anything inside each of its cells. This includes other cell arrays, structs, and very long lines with linebreaks. Because of this, a sensible display of a cell array is very dependent on its contents and what the user is interested on taking from them.

    What this means, is that it is up to the user to create a function that displays what he wants. I will provide an example that is useful for the case above, which is the most common case, i.e., a 2 dimensional cell array of short one-line strings. The solution is to create a format for printf on the fly from the longest string on each column like so:

    octave> a = {"foobar", "bar", "qux"; "baz", "nofnot", "zotr"};
    octave> col_width = max (cellfun (@numel, a)) +4
    col_width =
    
       10   10    8
    
    octave> row_template= [sprintf("%%%is", col_width) "\n"]
    row_template = %10s%10s%8s
    
    octave> printf (row_template, a'{:})
        foobar       bar     qux
           baz    nofnot    zotr
    

    Or on a single line:

    octave> printf ([sprintf("%%%is", max (cellfun (@numel, a))+4) "\n"], a'{:})
        foobar       bar     qux
           baz    nofnot    zotr
    

    More complex cell arrays, with a more complex but organized structure, can instead make use of Octave's dataframe. For example:

    octave> pkg load dataframe
    octave> C = {"Patient Name", "Volume", "Quality", "Owner"; "Joe", 200, .95, "MR"; "Dana", 186, .93, "MR"; "Cassidy", 197, .96, "SP"};
    octave> dataframe (C)
    ans = dataframe with 3 rows and 4 columns
    _1 Patient_Name Volume Quality Owner     
    Nr         char double  double  char     
     1          Joe    200 0.95000    MR     
     2         Dana    186 0.93000    MR     
     3      Cassidy    197 0.96000    SP