I would have the functions output numbers and no strings (which contain line returns), and then build a print function which is able to generate a table. The reason is that there is no easy way to put side by side strings when they don't all have the same width between all consecutive line returns.
If you don't want to update these functions so they output numbers or carefully trimmed arrays of characters (e.g. because you are not allowed bring modifications to their code), you can post-process the strings, e.g. by splitting them by line and adapting lengths or printing them using a padding.
To illustrate, imagine that we have 3 grabbed_values in a cell array (I generate a fake one):
print_state = 'Given values from data export\n\nStructure: PTV\n Mean Dose: %.1f\n Min Dose: %.1f\n Max Dose: %.1f\n Modal Dose: %.1f\n\nStructure: Rectum\n Mean Dose: %.1f\n Min Dose: %.1f\n Max Dose: %.1f\n Modal Dose: %.1f\n\nStructure: Bladder\n Mean Dose: %.1f\n Min Dose: %.1f\n Max Dose: %.1f\n Modal Dose: %.1f';
randValues = rand( 1, 12 ) ;
for k = 1 : 3
values = num2cell( randValues + 10*(k-1) ) ;
grabbed_values{k} = sprintf( print_state, values{:} ) ;
end
which gives:
>> grabbed_values
grabbed_values =
[1x282 char] [1x294 char] [1x294 char]
>> grabbed_values{1}
ans =
Given values from data export
Structure: PTV
Mean Dose: 0.2
Min Dose: 0.1
Max Dose: 0.1
Modal Dose: 0.6
Structure: Rectum
Mean Dose: 0.6
Min Dose: 0.4
Max Dose: 0.0
Modal Dose: 0.2
Structure: Bladder
Mean Dose: 0.5
Min Dose: 0.8
Max Dose: 0.8
Modal Dose: 0.9
>> grabbed_values{2}
ans =
Given values from data export
Structure: PTV
Mean Dose: 10.2
Min Dose: 10.1
Max Dose: 10.1
Modal Dose: 10.6
Structure: Rectum
Mean Dose: 10.6
Min Dose: 10.4
Max Dose: 10.0
Modal Dose: 10.2
Structure: Bladder
Mean Dose: 10.5
Min Dose: 10.8
Max Dose: 10.8
Modal Dose: 10.9
>> grabbed_values{3}
ans =
Given values from data export
Structure: PTV
Mean Dose: 20.2
Min Dose: 20.1
Max Dose: 20.1
Modal Dose: 20.6
Structure: Rectum
Mean Dose: 20.6
Min Dose: 20.4
Max Dose: 20.0
Modal Dose: 20.2
Structure: Bladder
Mean Dose: 20.5
Min Dose: 20.8
Max Dose: 20.8
Modal Dose: 20.9
We can do the following: first, we build a cell array of lines with one column per grabbed item:
nStr = numel( grabbed_values ) ;
for strId = 1 : nStr
lines = regexp( grabbed_values{strId}, sprintf('\n'), 'split' )' ;
allGrabbed(1:numel(lines), strId) = lines ;
end
where we use REGEXP because STRSPLIT would treat '\n\n' as a single '\n'. This builds the following cell array:
allGrabbed =
'Given values from data export' 'Given values from data export' 'Given values from data export'
'' '' ''
'Structure: PTV' 'Structure: PTV' 'Structure: PTV'
' Mean Dose: 0.8' ' Mean Dose: 10.8' ' Mean Dose: 20.8'
' Min Dose: 0.5' ' Min Dose: 10.5' ' Min Dose: 20.5'
' Max Dose: 0.3' ' Max Dose: 10.3' ' Max Dose: 20.3'
' Modal Dose: 0.1' ' Modal Dose: 10.1' ' Modal Dose: 20.1'
'' '' ''
'Structure: Rectum' 'Structure: Rectum' 'Structure: Rectum'
' Mean Dose: 0.6' ' Mean Dose: 10.6' ' Mean Dose: 20.6'
' Min Dose: 0.2' ' Min Dose: 10.2' ' Min Dose: 20.2'
' Max Dose: 0.1' ' Max Dose: 10.1' ' Max Dose: 20.1'
' Modal Dose: 0.8' ' Modal Dose: 10.8' ' Modal Dose: 20.8'
'' '' ''
'Structure: Bladder' 'Structure: Bladder' 'Structure: Bladder'
' Mean Dose: 0.5' ' Mean Dose: 10.5' ' Mean Dose: 20.5'
' Min Dose: 0.7' ' Min Dose: 10.7' ' Min Dose: 20.7'
' Max Dose: 0.1' ' Max Dose: 10.1' ' Max Dose: 20.1'
' Modal Dose: 0.4' ' Modal Dose: 10.4' ' Modal Dose: 20.4'
Then we compute the max line length and we build a formatSpec with padding, leaving e.g. a 2 white spaces gap:
maxLength = max( max( cellfun( @length, allGrabbed ))) ;
fSpec = [repmat( sprintf( '%%-%ds', maxLength+2 ), 1, nStr), '\n'] ;
And finally we build the side by side string:
temp = allGrabbed' ;
sideBySide = sprintf( fSpec, temp{:} ) ;
and we get:
>> sideBySide
sideBySide =
Given values from data export Given values from data export Given values from data export
Structure: PTV Structure: PTV Structure: PTV
Mean Dose: 0.8 Mean Dose: 10.8 Mean Dose: 20.8
Min Dose: 0.5 Min Dose: 10.5 Min Dose: 20.5
Max Dose: 0.3 Max Dose: 10.3 Max Dose: 20.3
Modal Dose: 0.1 Modal Dose: 10.1 Modal Dose: 20.1
Structure: Rectum Structure: Rectum Structure: Rectum
Mean Dose: 0.6 Mean Dose: 10.6 Mean Dose: 20.6
Min Dose: 0.2 Min Dose: 10.2 Min Dose: 20.2
Max Dose: 0.1 Max Dose: 10.1 Max Dose: 20.1
Modal Dose: 0.8 Modal Dose: 10.8 Modal Dose: 20.8
Structure: Bladder Structure: Bladder Structure: Bladder
Mean Dose: 0.5 Mean Dose: 10.5 Mean Dose: 20.5
Min Dose: 0.7 Min Dose: 10.7 Min Dose: 20.7
Max Dose: 0.1 Max Dose: 10.1 Max Dose: 20.1
Modal Dose: 0.4 Modal Dose: 10.4 Modal Dose: 20.4
All this looks huge, but it is just a few lines (that I shortened a bit by swapping dimensions when we build allGrabbed), assuming that you have a cell array grabbed_values of strings to put side by side:
nStr = numel( grabbed_values ) ;
for strId = 1 : nStr
lines = regexp( grabbed_values{strId}, sprintf('\n'), 'split' ) ;
allGrabbed(strId, 1:numel(lines)) = lines ;
end
maxLength = max( max( cellfun( @length, allGrabbed ))) ;
fSpec = [repmat( sprintf( '%%-%ds', maxLength+2 ), 1, nStr), '\n'] ;
sideBySide = sprintf( fSpec, allGrabbed{:} ) ;
An alternative is probably to build a MATLAB table after the split, but I have little experience with printing tables.
Best Answer