MATLAB Answers

Reading a csv file

Hello Matlab community! I'm a begginer at Matlab, and I was given a project to complete. There's a few more steps to it, but right now I'm a little stuck on one particular part. I'm trying to read variables and their values from an easily readable csv file. It needs to be easy to read and change because people will be changing the values. This is what the csv file contains:
Orbital Input Variables, Values, Units
Altitude, 841, km
OrbitalType, 0,
DesiredStaticGSD, 500,
ForwardMotionCompensationFactor, 1,
DetectorSpatialChannels, 2800,
FNumberTelescope, 1, #
RadiusEarth, 6378100, m
I will be using other similar csv files in my code. The code that I have right now is this:
T = readtable('OrbitalInputs.csv','HeaderLines',0,'ReadVariableNames',true);
display(T);
MyStruct.Remark = 'These are my imported variables';
for Count=1:size(T,1)
A=table2cell(T(Count,1));
B=table2cell(T(Count,2));
MyStruct.(A{1}) = B{1};
end
But I find this code a bit confusing and circular. Is there any easier way to do the same thing in an easier code? Or something more direct?
I'm also trying to take the variables imported from the csv file and assign the values of those variables to other variables in a different code I have, so that I can use them in some calculations. Are there any specific ways to do this or any suggestions for how I would go about that?
Thank you!

  댓글 수: 0

로그인 to comment.

태그

제품

답변 수: 3

Walter Roberson 님의 답변 16 Apr 2019
 채택된 답변

T = readtable('OrbitalInputs.csv','HeaderLines',0,'ReadVariableNames',true);
MyStruct = cell2struct(num2cell(T.(2)),T.(1));
MyStruct.Remark = 'These are my imported variables';
Note, however, that this will put the Remark field last in the struct, not first.

  댓글 수: 4

표시 이전 댓글 수: 1
vals = [{'These are my imported variables'}; num2cell(T.(2))];
names = [{'Remark'}; T.(1)];
MyStruct = cell2struct(vals, names);
Hi, it's mostly working for me, but I started getting this error and I am unsure how to fix it. Any ideas?
Error using cell2struct
Field names must be non-empty character vectors or a string scalars.
Error in Readcsv (line 18)
SNRInputs = cell2struct(num2cell(SNR.(2)),SNR.(1));
You have encountered a csv file that has an empty first entry on the line but has more data after that. It might be an empty first entry followed by a number, such as
DetectorSpatialChannels,2800,
,2830,
,2850,
FNumberTelecope,1,#
or it might have an empty line for some reason, such as
DetectorSpatialChannels,2800,
FNumberTelescope,1,#
either arrangement would lead to an empty string in the first column of SNR
If it is the second case, where you just have an empty line, then you can adjust by using
mask = ~cellfun(@isempty, SNR.(1));
SNRInputs = cell2struct(num2cell(SNR{mask,2}), SNR{mask,1});
but if it is the first case where there is an implied continuation of the field name, with the intention of storing a vector of results, like
DetectorSpatialChannels = [2800, 2830, 2850];
then that would take more work to handle.

로그인 to comment.


dpb 님의 답변 16 Apr 2019

You started off well w/ the readtable route...but, once you've got the table, then use the variables there, don't create new ones, particularly ones with inscrutable names regarding their purpose...
>> tOrbit=readtable('cordelia.csv','ReadRowNames',1); % read the file as a table w/ variable as row ID
>> tOrbit.Units=categorical(tOrbit.Units) % convert units to a categorical variable
tOrbit =
7×2 table
Values Units
__________ ___________
Altitude 841 km
OrbitalType 0 <undefined>
DesiredStaticGSD 500 <undefined>
ForwardMotionCompensationFactor 1 <undefined>
DetectorSpatialChannels 2800 <undefined>
FNumberTelescope 1 #
RadiusEarth 6.3781e+06 m
>> tOrbit('RadiusEarth',:) % access all of the given row--another table
ans =
1×2 table
Values Units
__________ _____
RadiusEarth 6.3781e+06 m
>> tOrbit('RadiusEarth','Values') % access one variable -- also returns a table
ans =
table
Values
__________
RadiusEarth 6.3781e+06
>> tOrbit{'RadiusEarth','Values'} % dereference to the underlying data type with {}
ans =
6378100
>>
An alternate way to do something similar altho the units field compounds the effort is to make the file in the form that it could be executed as an m-file (or the text read and interpreted) by writing the data lines as valid Matlab assignments. This does require more discipline upon the user to ensure the line is indeed valid code which may be too much to expect/demand.
As far as passing data to other routines, use argument lists and functions to pass the data -- then the calling routine can use whatever names it has independent of the called function as far as actual name; just have to have a defined interface for the routine/function.

  댓글 수: 2

I'm not sure I quite understand. To pass the data to other routines, would I need to enter all this into the command line? I'd be assigning the data value to other variables I have already coded. Excuse my confusion, I'm not great at this stuff.
Hello, I got the program to work for the most part, and I'm very happy about it. Unfortunately, I keep getting an error for Readcsv:
Error using cell2struct
Field names must be non-empty character vectors or a string scalars.
Error in Readcsv (line 18)
SNRInputs = cell2struct(num2cell(SNR.(2)),SNR.(1));
And I'm not sure how to fix this or what's causing the errors. Any ideas?

로그인 to comment.


Jeremy Hughes 님의 답변 16 Apr 2019

It's hard to say without know what you'll be doing with the data, but I'd reccomend using the table directly unless you need a different container. Most importantly, you should avoid looping over the rows.
e.g. T.Values
You can also assign your remark to
T.Properties.Description = 'These are my imported variables';

  댓글 수: 1

I do need it in the structure field unfortunately. It's part of the requirements for the project. Thank you for the tip though!

로그인 to comment.



Translated by