2015-08-27 1 views
0

У меня есть текстовый файл D с n-строками и 5 столбцами, которые я хочу прочитать. Каждая строка будет представлять вектор. Однако, когда значение равно NA Я хочу, чтобы оставить его пустым:читать текстовый файл с NA как пустой matlab

D:

122 12 10 NA NA 
110 10 30 45 87 
110 12 10 NA NA 
.. 

Я делаю это:

bid = fopen(D,'r'); 
bfile = textscan(bid,'%d %d %d %s %s','TreatAsEmpty',{'NA'}) 
var=122; 
IndVar=bfile {:,1}==var; 
rest=bfile(:,[2:end]) 
vecVar=rest(IndVar) 

Я wnat, чтобы получить векторы из строки без NA: vecVar = [12 10]; [10 30 45 87]; [12 10];

Я стараюсь это:

rest= rest(~isnan(rest)); 

Я получаю сообщение об ошибке:

Неопределенная функция 'IsNaN' для входных аргументов типа 'клетка'.

Я играл более часа, но все еще не могу понять это. Любая помощь будет очень признательна!

большое спасибо!

+0

Если вы наберете 'size (rest)' в окне Command, что вы получаете? –

+0

@ CST-Link size (rest) дает ans = 1 4. Хотя должен быть n-ряд X 4 .. – mil

+0

Дело в том, что 'textscan' полезен для получения данных * по столбцам *, но вам нужна фильтрация данных по строкам. –

ответ

1

Как указано в сообщении об ошибке, isnan работает только с числовыми массивами. Чтобы работать с массивом ячеек числовых массивов, используйте cellfun, который будет применять команду для каждой ячейки массива. В стороне, NaN внутренне на самом деле является числом (либо одиночным, либо двойным), поэтому вам нужно использовать цифровую версию NaN вместо текстовой строки 'NA' для ваших пустых значений, а var - это встроенная команда, поэтому вы захотите изменить это имя переменной.

Вам нужно будет уточнить немного, но, насколько я понимаю, учитывая входной файл, содержащий матрицу:

122 12 10 NA NA 
110 10 30 45 87 
110 12 10 NA NA 

вы ожидаете:

vecVar ={... 
    [12 10]; 
    [10 30 45 87 ]; 
    [12 10] 
    }; 

В моем первом ответе, я пропустил тот факт, что вы читали целые числа. Это даст результат выше, который я думаю, что вы после:

bid = fopen(d,'r'); 
% integers don't have NaN, so read in as float instead. 
% also, collect everything into a single matrix because it makes it. 
% easier to debug 
bfile = textscan(bid,'%f %f %f %f, %f', 'TreatAsEmpty', 'NA', 'CollectOutput', true); 
fclose(D); 

% convert from a cell to a matrix to make i 
bfile = bfile{1}; 
var=122; 
IndVar = bfile(:,1) == var; 
rest = bfile(:, 2:end); 

% Turn the matrix back into a cell with each row a single cell 
[nrows, ncols] = size(rest); 
rest = mat2cell(rest, ones(nrows, 1), ncols); 

% get rid of the NaN values 
rest = cellfun(@(x) x(~isnan(x)), rest, 'UniformOutput', false); 

Это создаст массив ячеек, где каждый элемент содержит вектор, который можно получить с помощью desired_vector = rest{index_of_your_choice};

+0

Спасибо. Тем не менее, я получаю эту ошибку: Undefined функция isnan для входных аргументов типа 'cell'. Ошибка в @ (x) все (~ isnan (x)) ... Когда я использую% d isntead для останова строки (IndVar), дает мне ans = [90x1 int32], когда я должен получить 1 x 4 .. Что я делаю не так? – mil

+0

Да, спасибо! Я получил «отдых», который является массивом ячеек. Как преобразовать его в обычный вектор? – mil

+0

также этот ответ устанавливает «отдых» в массив 90 x 2. Когда он отличается во второй строке ... он имеет 4 столбца, но все еще читает только первые 2 столбца. – mil

1

Вот код, который ставит в массиве ячеек val каждая строка числовых значений:

%'Number of columns' 
    NC = 5; 

    %'Read the strings' 
    f = fopen('test.txt', 'r'); 
    raw= textscan(f, repmat('%s',1,NC)); 
    fclose(f); 
    if numel(raw) ~= NC 
      error('Something is wrong with the file format'); 
    else 
      NR = numel(raw{1}); 
    end; 

    %'Convert data' 
    for c = 1:NC 
      for r = 1:NR 
        raw{c}{r} = sscanf(raw{c}{r}, '%d'); 
      end; 
    end; 

    %'Concatenate rows into val' 
    val = cell(1,NR); 
    buf = cell(1,NC); 
    for r = 1:NR 
      for c = 1:NC 
        buf{c} = raw{c}{r}; 
      end; 
      val{r} = [buf{:}]; 
    end; 

Вы не можете использовать нормальную матрицу для хранения значений, потому что есть строки с разным числом значений. Это означает, что векторы строк могут храниться только в массивах ячеек.

+0

Спасибо. Мне понадобилось некоторое время, чтобы получить этот код. Я получаю свой «val» из предыдущего кода. Интересно, как мне получить доступ к строке, где первый столбец равен «val»? – mil

+0

@mil не уверен, что я понимаю вопрос. Но с кодом, который я предоставил, вы получаете первую строку: «val {1}», вторая строка - «val {2}» и т. Д. Чтобы получить первый столбец во второй строке, можно написать «val {2 } (1) '. Чтобы узнать, сколько столбцов находится в третьей строке, можно использовать 'numel (val {3})'. Обратите внимание: если вы попытаетесь получить доступ к столбцам, в которых первоначально было значение 'NA', вы получите сообщение об ошибке. –

+0

Извините за звучание глупо. Но я все еще не могу понять. Я написал в моем коде val = 122; IndVar = bfile {:, 1} == val ;. Я получаю значение «val» где-то раньше. Поэтому мне интересно, как получить строку (с столбцами из 2: NC), где первый столбец == 122..i.e.I использовал индекс IndVar .. – mil