Reputation: 6668
I have a matrix called rf_rate
. Some of the rows are NaN
. I wish to replace these NaN's with a certain row of the rf_rate matrix
. So far I have the code below which is not giving me the correct answer.
miss_rf = isnan(rf_rate); % getting a logical matrix of where NaN's are
% this us_rf is a row from the rf_rate matrix (us_pos is a single number)
us_rf = repmat(rf_rate(us_pos, :), length(rf_rate(:, 1)), 1);
% this is where its going wrong
rf_rate(miss_rf==1, :) = us_rf(miss_rf(miss_rf==1), :);
My matrix is of size 56x11 but after the last line it goes to 611x11, why?
In my matrix rf_rate
there are two rows which are NaN
it is these two rows I want to replace.
Upvotes: 2
Views: 211
Reputation: 3476
If you have only entire rows with NaN
values and 'clean' rows everywhere else :
% Number of rows to replace :
Nrows=sum(all(isnan(rf_rate),2));
% Replace the rows if Nrows>0:
if Nrows>0
rf_rate(all(isnan(rf_rate),2),:)=repmat(rf_rate(us_pos,:),Nrows,1);
end
If you have a row of reference and you want, everytime a NaN appears in any other row, to replace it with the corresponding value in your row of reference :
% Create a column vector of length `numel(rf_rate)` by repeating the first row :
Corrector=reshape(repmat(rf_rate(us_pos,:),size(rf_rate,1),1),[],1);
% Use linear indexing to fetch the NaN locations and replace them :
rf_rate(isnan(rf_rate(:)))=Corrector(isnan(rf_rate(:)));
rf_rate=magic(10);
rf_rate([2 3 7],:)=NaN;
us_pos=1;
rf_rate =
92 99 1 8 15 67 74 51 58 40
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
85 87 19 21 3 60 62 69 71 28
86 93 25 2 9 61 68 75 52 34
17 24 76 83 90 42 49 26 33 65
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
79 6 13 95 97 29 31 38 45 72
10 12 94 96 78 35 37 44 46 53
11 18 100 77 84 36 43 50 27 59
% Apply code 1 :
% Number of rows to replace :
Nrows=sum(all(isnan(rf_rate),2));
% Replace the rows if Nrows>0:
if Nrows>0
rf_rate(all(isnan(rf_rate),2),:)=repmat(rf_rate(us_pos,:),Nrows,1);
end
Output
rf_rate =
92 99 1 8 15 67 74 51 58 40
92 99 1 8 15 67 74 51 58 40
92 99 1 8 15 67 74 51 58 40
85 87 19 21 3 60 62 69 71 28
86 93 25 2 9 61 68 75 52 34
17 24 76 83 90 42 49 26 33 65
92 99 1 8 15 67 74 51 58 40
79 6 13 95 97 29 31 38 45 72
10 12 94 96 78 35 37 44 46 53
11 18 100 77 84 36 43 50 27 59
rf_rate=magic(10);
us_pos=1;
NanPos=randi(numel(rf_rate),10,1);
NanPos(mod(NanPos,10)==1)=[];
rf_rate(NanPos)=NaN;
rf_rate =
92 99 1 8 15 67 74 51 58 40
98 80 7 14 16 73 55 57 64 41
4 NaN 88 20 22 54 56 NaN 70 NaN
85 87 19 21 3 60 62 69 71 28
86 93 25 2 9 61 68 75 52 34
17 24 76 83 90 42 49 26 33 65
23 5 82 89 91 48 30 32 39 66
79 6 13 95 97 29 31 38 45 72
NaN 12 94 NaN NaN 35 37 44 NaN 53
11 18 NaN 77 84 36 NaN 50 27 59
% Apply code 2 :
% Create a column vector of length `numel(rf_rate)` by repeating the first row :
Corrector=reshape(repmat(rf_rate(us_pos,:),size(rf_rate,1),1),[],1);
% Use linear indexing to fetch the NaN locations and replace them :
rf_rate(isnan(rf_rate(:)))=Corrector(isnan(rf_rate(:)));
Output :
rf_rate =
92 99 1 8 15 67 74 51 58 40
98 80 7 14 16 73 55 57 64 41
4 99 88 20 22 54 56 51 70 40
85 87 19 21 3 60 62 69 71 28
86 93 25 2 9 61 68 75 52 34
17 24 76 83 90 42 49 26 33 65
23 5 82 89 91 48 30 32 39 66
79 6 13 95 97 29 31 38 45 72
92 12 94 8 15 35 37 44 58 53
11 18 1 77 84 36 74 50 27 59
Note that the second version of the code works for bot cases.
Upvotes: 1
Reputation: 809
I haven't figured out exactly what's happening with your code, but from your description I think what you want is
rf_rate(isnan(rf_rate)) = rf_rate(us_pos,:);
Note that unlike what you write, us_rf
is not a row, but rather a matrix of the row repeated. Your code is taking that and inserting this several times.
Also note, this isn't particularly robust, and will fail if you have individual NaN
s that don't take up an entire row.
Upvotes: 0