# How to tell Matlab to ignore NaNs in calculations/loops

조회 수: 130(최근 30일)
Tobi83 2012년 8월 8일
Hi, I am trying to make some operations with Matlab but I need to ignore the generatedmissing Values / NaNs Matlab gives out after reading in the data from excel. Since now the code is only taking the empty cells and copy them to the new spreadsheet. Instead the NaNs should be ignored. (I am replicating a Finance paper which makes use of the momentum strategy described in Jegadeesh/Titman(1993).) The code is posted below
The code is taken to some part from paper which is about quite the same topic. I have made only some few channges. I Can't delete all the columns which have some NaNs in it.
The code as used is
s=-1+(1-(-1)).*rand(715,215);
stockdata=transpose(s);
stockdata(stockdata > 0.5) = NaN;
stockid=[1:715];
[totalmonths,totalstocks] = size(stockdata);% Number of months, number of stocks
period1 = 6; %order period
period2 = 6; % holding period
startmonth=14;
for i=1:totalmonths
nbrstocks(i) = totalstocks - sum(isnan(stockdata(i,:)));
end
for i = 1:length(period1)
for j = 1:length(period2)
p1 = period1(i);
p2 = period2(j);
Rwinner = zeros(totalmonths,1);
Rloser = zeros(totalmonths,1);
idwinner = zeros(totalmonths,round(max(nbrstocks)*0.33));% empty matrix for winners
idloser = zeros(totalmonths,round(max(nbrstocks)*0.33));% empty matrix for losers
for k = startmonth:totalmonths+1-p1-p2 % loop from start till end
start1 = k;
stop1 = start1+p1-1;
ordermonths = start1:stop1;
start2 = stop1+1;
stop2 = start2+p2-1;
holdmonths = start2:stop2;
nstocks = nbrstocks(k);
% order R for the ordering weeks
data1 = stockdata(ordermonths, 1:nstocks);
R1 = ones(1,nstocks);
for m = 1:length(ordermonths)
R1 = R1.*data1(m,:);
end
R1 = R1-1;
% select for the winners and losers
[B,idx] = sort(R1,'descend');
ncandidates = round(nstocks*0.33);
idwinner(k,1:ncandidates) = stockid(idx(1:ncandidates));
idloser(k,1:ncandidates) = stockid(idx(end-ncandidates+1:end));
% caculate the R for winners and losers in holding months
data2winner = stockdata(holdmonths, idx(1:ncandidates));
data2loser = stockdata(holdmonths, idx(end-ncandidates+1:end));
R2w = ones(1,ncandidates);
R2l = ones(1,ncandidates);
for m = 1:length(holdmonths)
R2w = R2w.*data2winner(m,:);
R2l = R2l.*data2loser(m,:);
end
R2w = R2w-1;
R2l = R2l - 1;
Rwinner(k) = mean(R2w);
Rloser(k) = mean(R2l);
end
xlswrite(fullfile(['strategy_' num2str(p1) '_' num2str(p2) '_''.xlsx']),Rwinner,'Rwinner');
xlswrite(fullfile(['strategy_' num2str(p1) '_' num2str(p2) '_''.xlsx']),Rloser,'Rloser');
xlswrite(fullfile(['strategy_' num2str(p1) '_' num2str(p2) '_''.xlsx']),idwinner,'idwinner');
xlswrite(fullfile(['strategy_' num2str(p1) '_' num2str(p2) '_''.xlsx']),idloser,'idloser');
end
end

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

### 답변(4개)

Oleg Komarov 2012년 8월 8일
편집: Oleg Komarov 2012년 8월 9일
If you have the Statistics or the Financial toolbox, use nanmean().
EDIT
What are you trying to do with:
% order R for the ordering weeks
data1 = stockdata(ordermonths, 1:nstocks);
R1 = ones(1,nstocks);
for m = 1:length(ordermonths)
R1 = R1.*data1(m,:);
end
R1 = R1-1;
the cumulative return? Then set the NaNs to 1.
idx = isnan(data1);
data1(idx) = 1;
R1 = prod(data1) - 1;
no need to loop, since prod() is vectorized.
Apply same concept here:
% caculate the R for winners and losers in holding months
data2winner = stockdata(holdmonths, idx(1:ncandidates));
data2loser = stockdata(holdmonths, idx(end-ncandidates+1:end));
R2w = ones(1,ncandidates);
R2l = ones(1,ncandidates);
for m = 1:length(holdmonths)
R2w = R2w.*data2winner(m,:);
R2l = R2l.*data2loser(m,:);
end
R2w = R2w-1;
R2l = R2l - 1;
AND then use nanmean().
##### 댓글 수: 6표시숨기기 이전 댓글 수: 5
Oleg Komarov 2012년 8월 9일
See my edit.

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

Albert Yam 2012년 8월 8일
How about just going low level. At the start of the loop (or where applicable),
if any(isnan(VARIABLE))
continue
end
##### 댓글 수: 4표시숨기기 이전 댓글 수: 3
Tobi83 2012년 8월 9일
Thanks for your help again. I tried it like this
if any(isnan(R1))
continue
[B,idx] = sort(R1,'descend');
end
but this gave me an RWinner of zeros. I used this as data in combination with the code above
s=-1+(1-(-1)).*rand(715,215);
stockdata=transpose(s);
stockdata(stockdata > 0.5) = NaN;
stockid=[1:715];

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

Sebastian Holmqvist 2012년 8월 9일
data_vec = [1 2 3 4 5 NaN 7 8 NaN 10 12];
data_vec(~isnan(data_vec))
ans =
1 2 3 4 5 7 8 10 12
##### 댓글 수: 3표시숨기기 이전 댓글 수: 2
Tobi83 2012년 8월 9일
Thanks again. This doesnt't work because the number of elements must agree in
R1 = R1.*data1(m,:);
You simulate data which looks like the one I am using by copying the following and using it instead of the xlsread commands:
s=-1+(1-(-1)).*rand(715,215);
stockdata=transpose(s);
stockdata(stockdata > 0.5) = NaN;
stockid=[1:715];

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

borge 2012년 12월 6일
Hi Tobi83,
I am attempting to do a similar analysis andI have attempted to a compile a code similar to yours, but ran into the same problem, so I was wondering how your code ended up looking like?
Best, borge

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

### 범주

Find more on Logical in Help Center and File Exchange

### Community Treasure Hunt

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

Start Hunting!

Translated by