Assigning row names using "RowNames" property assignment does not work for me
이전 댓글 표시
Why is it that I cannot use the table properties assignment syntax given here Create a Table (under section "Add Row Names") when trying to assign row names to my table "VISSIMoutput"? I want to assign row names based on the variable 'Detector' in this table. The code for the program "MesReader_McMaster.m" where this functionality is desired is attached. The original input txt file is also attached.
답변 (4개)
Peter Perkins
2015년 10월 23일
OK, I read your question and code in a hurry, and read "variable names" when you actually said "row names". Sorry about that. Here's what's going on:
You're reading the CSV file with the format '%C%f%f%f%f%f'. That turns the year numbers field in the file into a categorical vector, with 20 categories that are named '1901', '1902', '1911', ... '1992'. Those category names are strings not numbers, and the values in VISSIMoutput.Detector are categorical values, also not numbers. I can't answer the question of whether or not it makes sense to turn the year numbers into a categorical, but it may not be helpful. More below.
(Parenthetically, I will note that VISSIMoutput{:,{'Detector'}} is equivalent to VISSIMoutput.Detector, but the latter is certainly simpler.)
Then there's this:
RowDetName = num2cell(Rowarray);
That creates a cell array, but it's not a cell array of strings. It's a cell array of scalar categoricals, because num2cell splits a "homogeneuous" array into a cell array with one value per cell. What you really wanted was
RowDetName = cellstr(Rowarray);
And then you do this
VISSIMoutput.Properties.RowNames = VISSIMoutput.Detector;
which tries to assign a categorical array to the row names. That's what the error you're getting is saying. What you really wanted was
VISSIMoutput.Properties.RowNames = cellstr(VISSIMoutput.Detector);
But then as IA points out, you've got duplicate names, so you'd get an error there too. Row names have to be unique, as IA says, so that referring to one name gets you exactly one row.
The answer to the question, "Why do you want row names?" is usually that there are meaningful names for the rows of your table, and it's more straight-forward to say
data('theRowIWant',:)
than
data(strcmp(data.aVarWithNames,'theRowIWant'),:)
The former is an indexing operation; the latter a search. If you don't have unique names for each row, the latter is what you need. As IA said, the Detector values repeat every 20 rows.
You may be better off reading the years as numbers, and then doing things like
VISSIMoutput(VISSIMoutput.Detector==1901,:)
or whatever. But you'll have to decide that for yourself. Year numbers really are numbers, and 1920 - 1901 has a real meaning, so it may make sense to leave them as numbers. In some kinds of statistical models, it might also make sense to treat them as categorical predictors. There are other kinds of "numbers" which it probably never sense to treat as numeric: zip codes, for example. It makes no sense to subtract 01760 from 92037. Making them categorical prevents you from even trying.
If you reorganized your data to a "wide" format using unstack, then you could use the year numbers as row names. What would that look like? It seems like your data have 20 specific years, and then for each year, a set of three numeric values for each of the intervals (0,30), (30,60), ... (7170,7200) as defined by (From_Time, To_Time). So you might reorganize your table to have 20 rows and 241 variables. One variable containing the year, one variable for each of (0,30), (30,60), ... (7170,7200), and each of theose latter is itself a 20x3 numeric variable. Then you could have the years as row names. But you'd have to say '1901', not 1901, because row names are strings.
It's also possible that you want to leave the data in its current tall form, but turn From_Time and To_Time into one categorical variable whose category names are '(0,30)' '(30,60)', ... .
It all depends on what you want to do with the data. Hope this helps.
Image Analyst
2015년 10월 22일
Try this:
VISSIMoutput = readtable('vissim_v_1_Copy.txt', ...
'Delimiter',';',...
'ReadVariableNames',false)
VISSIMoutput.Properties.VariableNames = {'DetectorNo', 'FromTime', 'ToTime', 'Volume', 'Occupancy', 'Speed'}
댓글 수: 1
Image Analyst
2015년 10월 23일
Stephen, the problem is that you want to give names to the rows (for some unknown reason) but to do that your row names must be unique so you can refer to a particular row name and get one specific row, not a bunch of them. However, your DetectorNo repeat every 20 rows. So for 1901, it appears at row 1, row 21, row 41, etc. So you don't have unique names as required. See the help where it specifies/requires "cell array of nonempty, distinct strings". You don't have that.
Why do you want row names anyway? It's not necessary. What would you do if you had a unique name for each row? You can refer to the rows by their index you know - you don't have to use row names.
Peter Perkins
2015년 10월 23일
0 개 추천
Stephen, you're going to need to explain what goes wrong, because that code should work, and seems to work for me.
댓글 수: 2
Stephen Fry
2015년 10월 23일
Image Analyst
2015년 10월 23일
So, just post it here and delete the "Answer". Why do you want to name your rows anyway?
카테고리
도움말 센터 및 File Exchange에서 Logical에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!