MATLAB Answers

readtable not reading logical values as expected

7 ビュー (過去 30 日間)
Andrew Wisti
Andrew Wisti 2021 年 8 月 10 日
コメント済み: Adam Danz 2021 年 8 月 11 日
I am using version 9.9.0.1592791 (R2020b) Update 5.
I found this behavior while reading and writing tables via readtable() and writetable().
% First, I make a table and write it to file:
myint = 1;
mychar = {'1'};
mybool = true;
t = table();
t = addvars(t, myint);
t = addvars(t, mychar);
t = addvars(t, mybool)
writetable(t, 'mytable.csv');
% This gives the table t:
%{
t =
1×3 table
myint mychar mybool
_____ ______ ______
1 {'1'} true
%}
% and the .csv file:
%{
myint,mychar,mybool
1,1,1
%}
% Note that "true" is written as a "1" as is expected
% Now, I try to read the table, properly setting the options:
opts = detectImportOptions('mytable.csv');
opts = setvartype(opts,'myint','int8');
opts = setvartype(opts,'mychar','char');
opts = setvartype(opts,'mybool','logical');
t = readtable('mytable.csv',opts)
% Instead of the expected result of getting a table with values 1 (as an integer), "1" (as a char), and true (logical), I get:
%{
t =
1×3 table
myint mychar mybool
_____ ______ ______
1 {'1'} false
%}
% When I change my file to:
%{
myint,mychar,mybool
1,1,true
%}
% readtable() reads the data as expected, giving:
%{
t =
1×3 table
int char bool
___ _____ _____
1 {'1'} true
%}
Why is this happening? This is unexpected, especially considering that writetable writes logical values as '0' and '1'. Is this expected or is this a bug?
Note: When I use .xls instead of .csv, it behaves as expected.
  1 件のコメント
Adam Danz
Adam Danz 2021 年 8 月 10 日
Same behavior in R2021a. This is unexpected.
You should report this to tech support: Contact Us - MATLAB & Simulink
As a workaround, read in the logical column as double as then convert to logical.
opts = setvartype(opts,'mybool','double');
t = readtable('mytable.csv',opts);
t.mybool = logical(t.mybool);

サインインしてコメントする。

採用された回答

Jeremy Hughes
Jeremy Hughes 2021 年 8 月 10 日
編集済み: Jeremy Hughes 2021 年 8 月 10 日
The default results of detectImportOptions seeing "1" & "0" will be numeric, and the default logical reading expects "true","t" or "false","f" (case insensitive), but this is overridable.
T = array2table(randn(6,3)>0)
T = 6×3 table
Var1 Var2 Var3 _____ _____ _____ true true true true true false true false true true true true false false true true false true
writetable(T,"mytable.csv","WriteVariableNames",false)
opts = delimitedTextImportOptions("NumVariables",3,...
"VariableNames",["myint","mychar","mybool"],...
"VariableTypes",["int8","char","logical"]);
getvaropts(opts,'mybool')
ans =
LogicalVariableImportOptions with properties: Variable Properties: Name: 'mybool' Type: 'logical' FillValue: 0 TreatAsMissing: {} QuoteRule: 'remove' Prefixes: {} Suffixes: {} EmptyFieldRule: 'missing' Logical Options: TrueSymbols: {'true' 't'} FalseSymbols: {'false' 'f'} CaseSensitive: 0
You can set what gets treated as true or false with the true and false symbols.
opts = setvaropts(opts,'mybool',...
"TrueSymbols",["t","true","1"],...
"FalseSymbols",["f","false","0"]);
t = readtable('mytable.csv',opts)
t = 6×3 table
myint mychar mybool _____ ______ ______ 1 {'1'} true 1 {'1'} false 1 {'0'} true 1 {'1'} true 0 {'0'} true 1 {'0'} true
Note: This will only match literally 0 and 1, not "0.0" as false or "2" true, but should be good enough for most cases.
  9 件のコメント
Adam Danz
Adam Danz 2021 年 8 月 11 日
Thanks for the explanation, @Jeremy Hughes. I also second the enhancement request to consider 0=false ~0=true when the variable type is declared as logical.

サインインしてコメントする。

その他の回答 (0 件)

製品


リリース

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by