Смешанные типы данных Таблицы Matlab

Я хочу использовать makeValidName работать на следующих данных:

Id  Val Random          Desc
a   1.1 0.036835624 Bread Cheese
b   2.2 0.020442492 Fish Bread
c   -3.3    0.020050676 Cheese Fish
d   #N/A    0.017619332 Bread Cheese
e   -5.4    0.014973153 Fish Bread
f   6.6 0.014648887 Cheese Fish
g   -7.6    0.014071844 Bread Cheese
h   8   0.014013118 Fish Bread

Однако, когда я импортирую таблицу (прочитанную из xlsx с помощью readtable), она выглядит так:

inputData =

 Id             Val              Random          Desc     
____    ____________________    ________    ______________

'a '    '1.1'                   0.036836    'Bread Cheese'
'b'     '2.2'                   0.020442    'Fish Bread'  
'c'     '-3.3'                  0.020051    'Cheese Fish' 
'd'     'ActiveX VT_ERROR: '    0.017619    'Bread Cheese'
'e'     '-5.4'                  0.014973    'Fish Bread'  
'f'     '6.6'                   0.014649    'Cheese Fish' 
'g'     '-7.6'                  0.014072    'Bread Cheese'
'h'     '8'                     0.014013    'Fish Bread'  

Как я могу предотвратить превращение записей в Val от чисел к строкам? Это делает невозможным использование makeValidName, Мне нужно подать заявку makeValidName во всех строках и столбцах, так как таблицы очень большие и не представляется возможным назвать соответствующие столбцы по отдельности. Что тогда будет самым элегантным способом достижения этого?

Текущий код:

varnames = inputData.Properties.VariableNames;
for ii = 1:length(varnames)

inputData.(varnames{ii})= matlab.lang.makeValidName(inputData.(varnames{ii}));

end

Выдает ошибку:

Ошибка при использовании matlab.lang.makeValidName (строка 72) Первым вводом должен быть массив строк или векторных ячеек строк.

и дает нежелательные результаты в столбцах, таких как Val:

inputData =

Id            Val             Random         Desc     
___    __________________    ________    _____________

'a'    'x1_1'                0.036836    'BreadCheese'
'b'    'x2_2'                0.020442    'FishBread'  
'c'    'x_3_3'               0.020051    'CheeseFish' 
'd'    'ActiveXVT_ERROR_'    0.017619    'BreadCheese'
'e'    'x_5_4'               0.014973    'FishBread'  
'f'    'x6_6'                0.014649    'CheeseFish' 
'g'    'x_7_6'               0.014072    'BreadCheese'
'h'    'x8'                  0.014013    'FishBread'

1 ответ

Решение

Поскольку кажется, что использование Excel в середине создает больше головной боли. Я бы порекомендовал использовать basic режим, который облегчит некоторые ошибки синтаксического анализа.

Из документации:

basic Режим по умолчанию для систем без Excel для Windows. В basic Режим, readtable:

  • Читает только файлы XLS, XLSX, XLSM, XLTX и XLTM.
  • Не поддерживает 'Range' Аргумент пара имя-значение при чтении файлов XLS.
  • Импортирует все даты в виде серийных номеров Excel. Серийные номера даты Excel используют другую справочную дату, чем номера даты MATLAB®.

Это позволяет нам использовать TreatAsEmpty Аргумент пара имя-значение, поскольку он будет правильно анализировать числовые столбцы.

inputData = readtable('test.xlsx', 'Basic', 1, 'TreatAsEmpty', '#N/A');

Который возвращается для примера:

inputData = 

    Id     Val      Random          Desc     
    ___    ____    ________    ______________

    'a'     1.1    0.036836    'Bread Cheese'
    'b'     2.2    0.020442    'Fish Bread'  
    'c'    -3.3    0.020051    'Cheese Fish' 
    'd'     NaN    0.017619    'Bread Cheese'
    'e'    -5.4    0.014973    'Fish Bread'  
    'f'     6.6    0.014649    'Cheese Fish' 
    'g'    -7.6    0.014072    'Bread Cheese'
    'h'       8    0.014013    'Fish Bread'

Теоретически это должно означать, что числовые столбцы данных double массивы и строки остаются в cell массивы. Поэтому использовать matlab.lang.makeValidName Вы можете проверить каждый столбец с iscell чтобы увидеть, если это массив ячеек:

varnames = inputData.Properties.VariableNames;
for ii = 1:length(varnames)
    if iscell(inputData.(varnames{ii}))
        % If they're strings they're in a cell array
        inputData.(varnames{ii})= matlab.lang.makeValidName(inputData.(varnames{ii}));
    end
end

Который возвращает:

inputData = 

    Id     Val      Random         Desc     
    ___    ____    ________    _____________

    'a'     1.1    0.036836    'BreadCheese'
    'b'     2.2    0.020442    'FishBread'  
    'c'    -3.3    0.020051    'CheeseFish' 
    'd'     NaN    0.017619    'BreadCheese'
    'e'    -5.4    0.014973    'FishBread'  
    'f'     6.6    0.014649    'CheeseFish' 
    'g'    -7.6    0.014072    'BreadCheese'
    'h'       8    0.014013    'FishBread'  
Другие вопросы по тегам