MATLAB: Last row in a matrix is not computing :( - matlab

So i have a homogenous numeric array as shown below. I converted this array to a table using the array2Table function. What is shown below is simply the variabe names being applied to the array. I have column names but I would like to have row names as well. Is it the fact that the array is of one variable class that I cant do this?
T = array2table(C,'RowNames',{'','T0','T1','T2','T3','T4'},'VariableNames' ,{'to','t1','t2','t3','t4','t5','t6','t7','t8','t9','t10'})
T =
6×11 table
to t1 t2 t3 t4 t5 t6 t7 t8 t9 t10
___ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______
0 18 36 54 72 90 108 126 144 162 180
15 15 15 15 15 15 15 15 15 15 15
325 304.17 303.4 295.01 293.52 288.3 286.56 282.49 280.5 276.99 274.8
325 325 315.67 314.35 308.58 306.86 302.38 300.33 296.49 294.19 290.74
325 325 325 320.82 319.8 315.43 313.61 309.61 307.35 303.69 301.2
325 325 325 325 321.25 319.95 315.9 313.85 310.05 307.63 304.1
The errors that Im getting here are:
Error using matlab.internal.tabular.private.rowNamesDim/validateAndAssignLabels (line 109)
The RowNames property must be a cell array, with each element containing one nonempty character vector.
Error in matlab.internal.tabular.private.tabularDimension/setLabels (line 173)
obj = obj.validateAndAssignLabels(newLabels,indices,fullAssignment,fixDups,fixEmpties,fixIllegal);
Error in matlab.internal.tabular.private.tabularDimension/createLike_impl (line 355)
obj = obj.setLabels(dimLabels,[]);
Error in matlab.internal.tabular.private.tabularDimension/createLike (line 62)
obj = obj.createLike_impl(dimLength,dimLabels);
Error in tabular/initInternals (line 206)
t.rowDim = t.rowDim.createLike(nrows,rowLabels);
Error in table.init (line 327)
t = initInternals(t, vars, numRows, rowLabels, numVars, varnames);
Error in array2table (line 64)
t = table.init(vars,nrows,rownames,nvars,varnames);

The error you're getting is
The RowNames property must be a cell array, with each element containing one nonempty character vector.
Here is a valid version:
T = array2table(C,'RowNames',{'T','T0','T1','T2','T3','T4'},'VariableNames' ,{'to','t1','t2','t3','t4','t5','t6','t7','t8','t9','t10'})
You need to change the first element of RowNames array to be nonempty character vector, e.g. 'T' instead of ''.

Related

save a cell array in matlab as .xlsx or .csv file

I have a cell array myFile 637x16. The first row of the cell array is made of strings, because they will be the columns' labels in the .xlsx/.csv file.
From the second row on, the cell array is made of some columns with strings, and some columns with numbers.
I would like to export this cell array as a .xlsx or .csv file.
Here is an example of what I have:
'subject' 'PeakA' 'PeakL' 'number' 'epoch' 'code' 'type' 'latency' 'nitem' 'condition' 'ia' 'cover' 'variety' 'init_index' 'init_time' 'urevent'
5 3.50 82 13 1 201011 'pre' 2502 201 1 1 'y' 'h' 13 13.92 13
5 -1.27 112 55 2 61011 'pre' 8213 61 1 1 'y' 'h' 55 53.90 55
5 6.59 99 85 3 124011 'pre' 13924 124 1 1 'y' 'h' 85 82.45 85
5 12.65 105 127 4 178011 'pre' 19635 178 1 1 'y' 'h' 127 122.43 127
5 -0.35 105 157 5 89011 'pre' 25346 89 1 1 'y' 'h' 157 150.98 157
5 10.29 93 163 6 132011 'pre' 31057 132 1 1 'y' 'h' 163 156.69 163
5 4.61 65 193 7 166011 'pre' 36768 166 1 1 'y' 'h' 193 185.25 193
5 1.45 51 199 8 212011 'pre' 42479 212 1 1 'y' 'h' 199 190.96 199
I tried:
xlswrite('filename.xlsx', myFile);
but it gives me this error:
Warning: Could not start Excel server for export.
XLSWRITE will attempt to write file in CSV format.
> In xlswrite (line 174)
Error using xlswrite (line 187)
An error occurred on data export in CSV format.
Caused by:
Error using dlmwrite (line 112)
The input cell array cannot be converted to a matrix.
If you have a sufficiently recent version of Matlab (R2013b or older), writetable is your friend.
%# create a table
tbl = cell2table(yourCellArray(2:end,:),'variableNames',yourCellArray(1,:));
%# write to file
writetable(tbl,'filename.xlsx')
If you want to use xlswrite, it may be worth converting all data to string first, or to write the variable names separately, before you write the rest - I believe Matlab checks data types on the first row, which can cause typecast errors.

Missing data in repeated measure model

I am using the matlab function fitrm to fit repeated measures model in order to investigate whether elements grouped according to Grouping1 have statistically different means for the variable measured at time t1,t2,t3,t4 (var_t1,var_t2,var_t3,var_t4).
My data look like the ones in the table:
Grouping1 Grouping2 Gender Age BMI var_t1 var_t2 var_t3 var_t4
______ ___________ ______ ______ ______ ____________ ____________ ____________ ____________
C B Male 60 24.802 836 608 746 NaN
C A Male 67 19.818 242 544 460 483
... ...
D C Female 65 21.631 621 468 NaN NaN
As you can see from I have some missing data for var_t3 and var_t4.
Can I still use fitrm?
If fit a repeated measures model, where var_t1,-var_t4 are the responses and Grouping1, Grouping2, Gender, Age and BMI are the predictor variables
Time = [1:4]';
rm = fitrm(table,'var_t1-var_t4 ~ Grouping1 + Grouping2 + Gender + Age + BMI','WithinDesign',Time)
the function doesn't return error, but I don't know if the results have any meaning...

Pivot table in kdb+/q

I'm trying to pivot some trade data in KDB/q. Although my data are only slightly different from the working example on the website (see the general pivot function: http://code.kx.com/q/cookbook/pivoting-tables/),
I can't get the function to work, even after several hours of trying (I'm very new to KDB).
Put simply, I'm trying to go from this table:
q)5# trades_agg
date sym time exchange buysell| shares
--------------------------------------| ------
2009.01.05 aaca 09:30 BATS B | 484
2009.01.05 aaca 09:30 BATS S | 434
2009.01.05 aaca 09:30 NASDAQ B | 235
2009.01.05 aaca 09:30 NASDAQ S | 429
2009.01.05 aaca 09:30 NYSE B | 309
to this one:
date sym time | BATSsharesB BATSsharesS NASDAQsharesB ...
----------------------| -----------------------------------------------
2009.01.05 aaca 09:30 | 484 434 235 ...
... | ...
I'll provide a working example to illustrate things:
// Create data
qpd:5*2*4*"i"$16:00-09:30
date:raze(100*qpd)#'2009.01.05+til 5
sym:(raze/)5#enlist qpd#'100?`4
sym:(neg count sym)?sym
time:"t"$raze 500#enlist 09:30:00+15*til qpd
time+:(count time)?1000
exchange:raze 500#enlist raze(qpd div 3)#enlist`NYSE`NASDAQ`BATS
buysell:raze 500#enlist raze(qpd div 2)#enlist`B`S
shares:(500*qpd)?100
trades:([]date;sym;time;exchange;buysell;shares)
//I then aggregate the data into equal sized buckets
trades_agg: select sum shares by date, sym, time: 15 xbar time.minute, exchange, buysell from trades
// pivot function from the code.kx.com website
piv:{[t;k;p;v;f;g]
v:(),v;
G:group flip k!(t:.Q.v t)k;
F:group flip p!t p;
count[k]!g[k;P;C]xcols 0!key[G]!flip(C:f[v]P:flip value flip key F)!raze
{[i;j;k;x;y]
a:count[x]#x 0N;
a[y]:x y;
b:count[x]#0b;
b[y]:1b;
c:a i;
c[k]:first'[a[j]#'where'[b j]];
c}[I[;0];I J;J:where 1<>count'[I:value G]]/:\:[t v;value F]}
I subsequently apply this pivot function to the example with the functions f and g set to their default (::) values but I get an error message:
piv[`trades_agg;`date`sym`time;`exchange`buysell;`shares;(::);(::)]
Even when I use the suggested f and g functions it doesn't work:
f:{[v;P]`$raze each string raze P[;0],'/:v,/:\:P[;1]}
g:{[k;P;c]k,(raze/)flip flip each 5 cut'10 cut raze reverse 10 cut asc c}
I don't get why this is not working correctly since it is so close to the example on the website.
This is a self-contained version that's easier to use:
tt:1000#0!trades_agg
piv:{[t;k;p;v]
/ controls new columns names
f:{[v;P]`${raze " " sv x} each string raze P[;0],'/:v,/:\:P[;1]};
v:(),v; k:(),k; p:(),p; / make sure args are lists
G:group flip k!(t:.Q.v t)k;
F:group flip p!t p;
key[G]!flip(C:f[v]P:flip value flip key F)!raze
{[i;j;k;x;y]
a:count[x]#x 0N;
a[y]:x y;
b:count[x]#0b;
b[y]:1b;
c:a i;
c[k]:first'[a[j]#'where'[b j]];
c}[I[;0];I J;J:where 1<>count'[I:value G]]/:\:[t v;value F]};
q)piv[`tt;`date`sym`time;`exchange`buysell;enlist `shares]
date sym time | BATS shares B BATS shares S NASDAQ shares B NASDAQ sha..
---------------------| ------------------------------------------------------..
2009.01.05 adkk 09:30| 577 359 499 452 ..
2009.01.05 adkk 09:45| 882 501 339 467 ..
2009.01.05 adkk 10:00| 620 513 411 128 ..
2009.01.05 adkk 10:15| 501 544 272 544 ..
2009.01.05 adkk 10:30| 291 594 363 331 ..
2009.01.05 adkk 10:45| 867 500 498 536 ..
2009.01.05 adkk 11:00| 624 632 694 493 ..
2009.01.05 adkk 11:15| 99 704 600 299 ..
2009.01.05 adkk 11:30| 269 394 280 392 ..
2009.01.05 adkk 11:45| 635 744 758 597 ..
2009.01.05 adkk 12:00| 562 354 498 405 ..
2009.01.05 adkk 12:15| 416 437 303 492 ..
2009.01.05 adkk 12:30| 447 699 370 302 ..
2009.01.05 adkk 12:45| 336 647 512 245 ..
2009.01.05 adkk 13:00| 692 457 497 553 ..
Your table is keyed so unkey it:
trades_agg:0!select sum shares by date, sym, time: 15 xbar time.minute,exchange,buysell from trades
And define your g as:
g:{[k;P;c]k,c}
Best way to figure out what the f/g needs to be is to define it with a breakpoint and then investigate the variables
g:{[k;P;c]break}
I found it difficult to understand the original piv function in Ryan's answer, so I updated it by adding some comments + more readable variable names HTH
piv:{[table; rows; columns; vals]
/ make sure args are lists
vals: (),vals;
rows: (),rows;
columns: (),columns;
/ Get columns of table corresponding to those of row labels and calculate groups
/ group returns filteredValues dict whose keys are the unique row labels and vals are the row indices of each group e.g. (0 1 3; 2 4; ...)
rowGroups: group rows#table;
rowGroupIdxs: value rowGroups;
rowValues: key[rowGroups];
/ Similarly, get columns of table corresponding to those of column labels and calculate groups
colGroups: group columns#table;
colGroupIdxs: value colGroups;
colValues: key colGroups;
getPivotCol: {[rowGroupStartIdx; nonSingleRowGroups; nonSingleRowGroupsIdx; vals; colGroupIdxs]
/ vals: the list of values for this particular value-column combination
/ colGroupIdxs: the list of indices for this particular column group
/ We only care about vals that should belong in this pivot column - we need to filter out vals not part of this column group
filteredValues: count[vals]#vals[0N];
filteredValues[colGroupIdxs]: vals[colGroupIdxs];
/ Equivalent to filteredValues <> 0N
hasValue: count[vals]#0b;
hasValue[colGroupIdxs]: 1b;
/ Seed off pivot column with the first (filtered) value of each row group
/ This will be correct for row groups of size 1 as no aggregation needs to occur
pivotCol: filteredValues[rowGroupStartIdx];
/ Otherwise, for the row groups larger than 1, get the first (filtered) value
pivotCol[nonSingleRowGroupsIdx]: first'[filteredValues[nonSingleRowGroups]#'where'[hasValue[nonSingleRowGroups]]];
pivotCol
}
/ Groups with more than 1 row (these are the ones that will need aggregating)
nonSingleRowGroupsIdx: where 1 <> count'[rowGroupIdxs];
/ Get resulting pivot column for each combination of column and value fields
pivotCols: raze getPivotCol[rowGroupIdxs[;0]; rowGroupIdxs[nonSingleRowGroupsIdx]; nonSingleRowGroupsIdx] /:\: [table[vals]; colGroupIdxs]
/ Columns names are the cross-product of column and value fields
colNames:`${raze "" sv vals} each string raze (flip value flip colValues),'/:vals;
/ Finally, stitch together row and column headings with pivot data to obtain final table
rowValues!flip colNames!pivotCols
};
I also made a small change to formatting of columns names for my needs btw

Concatenation of Matlab strings

I want to make a Matlab function that takes two matrices A and B (of the same size) and combines them in a certain way to give an output that can be used in Latex - table.
I want the first row of the output matrix to consist of the first row of matrix A, with ampersands (&) in between them, and that ends with an double backslash.
The second row should be the first row of B with parentheses around them, and ampersands in between. And so on for the rest of A and B.
If I let A=rand(1,2), I could do this by using [num2str(A(1)), ' & ', num2str(A(2)),' \\'] and so on.
But I want to be able to make a function that does this for any size of the matrix A. I guess I have to make cell structures in some way. But how?
This could be one approach -
%// First off, make the "mixed" matrix of A and B
AB = zeros(size(A,1)*2,size(A,2));
AB(1:2:end) = A;
AB(2:2:end) = B;
%// Convert all numbers of AB to characters with ampersands separating them
AB_amp_backslash = num2str(AB,'%1d & ');
%// Remove the ending ampersands
AB_amp_backslash(:,end-1:end) = [];
%// Append the string ` \\` and make a cell array for the final output
ABcat_char = strcat(AB_amp_backslash,' \\');
ABcat_cell = cellstr(ABcat_char)
Sample run -
A =
183 163 116 50
161 77 107 91
150 124 56 46
B =
161 108 198 4
198 18 14 137
6 161 188 157
ABcat_cell =
'183 & 163 & 116 & 50 \\'
'161 & 108 & 198 & 4 \\'
'161 & 77 & 107 & 91 \\'
'198 & 18 & 14 & 137 \\'
'150 & 124 & 56 & 46 \\'
' 6 & 161 & 188 & 157 \\'
You can use sprintf, it will repeat the format spec as many times as required until all input variables are processed:
%combine both to one matrix
C=nan(size(A).*[2,1]);
C(1:2:end)=A;
C(2:2:end)=B;
%print
sprintf('%f & %f \\\\\n',C.')
The transpose (.') is required to fix the ordering.

MATLAB - extract selected rows in a table based on some criterion

Let's say I have a table like this:
post user date
____ ____ ________________
1 A 12.01.2014 13:05
2 B 15.01.2014 20:17
3 A 16.01.2014 05:22
I want to create a smaller table (but not delete the original one!) containing all posts of - for example - user A including the dates that those were posted on.
When looking at MATLAB's documentation (see the very last part for deleting rows) I discovered that MATLAB allows you to create a mask for a table based on some criterion. So in my case if I do something like this:
postsA = myTable.user == 'A'
I get a nice mask vector as follows:
>> postsA =
1
0
1
where the 1s are obviously those rows in myTable, which satisfy the rule I have given.
In the documention I have pointed at above rows are deleted from the original table:
postsNotA = myTable.user ~= 'A' % note that I have to reverse the criterion since I'm choosing stuff that will be removed
myTable(postsNotA,:) = [];
I would however - as stated above - like to not touch my original table. One possible solution here is to create an empty table with two columns:
post date
____ ____
interate through all rows of my original table, while also looking at the current value of my mask vector postsA and if it's equal to 1, copy the two of the columns in that row that I'm interested in and concatenate this shrunk row to my smaller table. What I'd like to know is if there is a more or less 1-2 lines long solution for this problem?
Assuming myTable is your original table.
You can just do
myTable(myTable.user == 'A',:)
Sample Code:
user = ['A';'B';'A';'C';'B'];
Age = [38;43;38;40;49];
Height = [71;69;64;67;64];
Weight = [176;163;131;133;119];
BloodPressure = [124 93; 109 77; 125 83; 117 75; 122 80];
T = table(user,Age,Height,Weight,BloodPressure)
T(T.user=='A',:)
Gives:
T =
user Age Height Weight BloodPressure
____ ___ ______ ______ _________________________
A 38 71 176 124 93
B 43 69 163 109 77
A 38 64 131 125 83
C 40 67 133 117 75
B 49 64 119 122 80
ans =
user Age Height Weight BloodPressure
____ ___ ______ ______ _________________________
A 38 71 176 124 93
A 38 64 131 125 83