How do I parse and erase from a string while importing CSV with tableread?

조회 수: 2(최근 30일)
I have found extractBefore, but how do I succinctly apply it to each opts.VariableNames element? Should I use cellfun? I will try it instead of a for loop, but I don't see how to use cellfun for a function requiring an input argument (namely, '_').
Why does MATLAB not allow for the following 'intuitive' syntax?
>> opts.VariableNames(:) = extractBefore(opts.VariableNames(:),'_')
Error using matlab.io.ImportOptions/set.VariableNames (line 185)
Expected a cell array of valid variable names.
>> opts.VariableNames = extractBefore(opts.VariableNames,'_')
Error using matlab.io.ImportOptions/set.VariableNames (line 185)
Expected a cell array of valid variable names.
The following code is what I am seeking to improve with this task, by automatically truncating the latter column names.
filepath = 'easy.csv';
opts = detectImportOptions(filepath, 'NumHeaderLines', 1);
opts = setvartype(opts,opts.VariableNames, 'double');
opts.VariableNames(1)={'Dose'};
DVH = readtable(filepath,opts)
  댓글 수: 1
Guillaume
Guillaume 2018년 1월 23일
Why does MATLAB not allow for the following 'intuitive' syntax?
>> opts.VariableNames(:) = extractBefore(opts.VariableNames(:),'_')
Because
extractBefore(opts.VariableNames{1},'_')
returns an empty char array (since VariableNames{1} doesn't have a _) which is not a valid variable name.
opts.VariableNames(2:end) = extractBefore(opts.VariableNames(2:end),'_')
would have worked.
By the way, note that the (:) in VariableNames(:) was pointless in your original code. The only thing that it did is transpose the cell array from a row vector to a column vector.

댓글을 달려면 로그인하십시오.

채택된 답변

Daniel Bridges
Daniel Bridges 2018년 1월 23일
편집: Daniel Bridges 2018년 1월 25일
The following code generates the table as desired.
function data = ReadMIMDVH(filepath)
opts = detectImportOptions(filepath, 'NumHeaderLines', 1);
opts = setvartype(opts,opts.VariableNames, 'double');
opts.VariableNames(1)={'Dose_'};
opts.VariableNames = extractBefore(opts.VariableNames,'_');
data = readtable(filepath,opts);
end
However, I hope someone will teach me how to accomplish this result in one line (via cellfun?) instead of four lines with a function.
  댓글 수: 3
Daniel Bridges
Daniel Bridges 2018년 1월 25일
편집: Daniel Bridges 2018년 1월 25일
I just reduced it to one line as Walter suggested and it works; I've edited my answer to simplify accordingly.
I think I made it into a function because the extractBefore documentation says a string is expected, and I neglected to check the Input Arguments section to see that a cell array of character vectors was also permitted. Sorry for the confusion; thanks for the clarity.

댓글을 달려면 로그인하십시오.

추가 답변(1개)

Peter Perkins
Peter Perkins 2018년 1월 24일
Fixing the names in the importOptions setting is one choice, but an alternative might have been to patch up the names after reading the file with readtable (you'd still have to skip the header line). Perhaps something like
DVH.Properties.VariableNames{1} = 'Dose'; DVH.Properties.VariableNames(2:end) = extractBefore(DVH.Properties.VariableNames(2:end), '_')
  댓글 수: 3
Peter Perkins
Peter Perkins 2018년 1월 25일
Daniel, I'm usually an advocate of fixing things at their source. My suggestion was more about simplicity. But as Guillaume says, if you're using detectimportoptions anyway ...
Guillaume, I hear you about frustrating, but it's a tension between backwards compatibility, and better new behavior. We try to walk a fine line between providing better behavior by default, and not breaking code that relied on the older behavior.

댓글을 달려면 로그인하십시오.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by