# Moving through varibles in for loop (ugly)...

1 view (last 30 days)
Chris E. on 19 Jul 2013
Hello everyone,
Well I have an issue where I have to set some data, I'm a little lost on how to do it, but I made a "cheating" way of doing this... A little background, the data that is coming in sometimes has bad data, it is very noticeable in the plots because the bad points of data show up as the same value over and over, so I devised a way to look through the needed variables and turn the bad data to ether 0 or NaN's so when it plots, we can see the useful information.
So here is the issue, it seems like bad code, sludgy and ugly (maybe its nice, I don't know...). I was hoping for second opinions, advice or help to make it better. If anyone knows how to make it better or how to clean it up then please help me out, I appreciate any help and learning I can get. Here is an example of the code:
RMSVal = [125.3226 125.3226 339.9060 101.2705 131.3098 71.1203 125.3226 125.3226];
AreaVal = [228.4361 228.4361 33.5430 96.2065 70.9288 30.4743 228.4361 228.4361];
meanVal = [-3.2270 -3.2270 -3.2308 -3.2542 -3.2136 -3.1690 -3.2270 -3.2270];
RMSValStd = [6.8557 6.8557 34.6666 3.4756 11.6483 5.6991 6.8557 6.8557];
AreaValStd = [322.9295 322.9295 77.5901 85.3251 162.5888 63.1066 322.9295 322.9295];
meanValStd = [0.0069 0.0069 0.0244 0.0035 0.0116 0.0057 0.0069 0.0069];
c = 1;
for var = {'RMSVal'; 'AreaVal'; 'RMSValStd'; 'AreaValStd'; 'meanVal'; 'meanValStd'}'
nv = var{1};
[amount,vals]=hist(eval(nv),unique(eval(nv)));
rm = vals(amount > 1);
if c <= 4
eval([nv '(' nv '== rm) = 0']) %turns to = 0
else
eval([nv '(' nv '== rm) = NaN']) %turns to = NaN
end
c = c + 1;
end
Thank you!
Cedric Wannaz on 19 Jul 2013
Wouldn't it be enough to check repetitions on one variable only?

Cedric Wannaz on 19 Jul 2013
Edited: Cedric Wannaz on 19 Jul 2013
If it is enough to check one variable only and update them all accordingly, one solution could be:
dup = ~diff(RMSVal) ; % Is duplicated.
if any(dup)
lId = [dup, false] | [false, dup] ;
RMSVal(lId) = 0 ;
AreaVal(lId) = 0 ;
meanVal(lId) = 0 ;
RMSValStd(lId) = 0 ;
AreaValStd(lId) = NaN ;
meanValStd(lId) = NaN ;
end
If all data should be checked, but invalid elements in one array invalidate the other arrays too at the same locations (which is not what you have):
buffer = [RMSVal; AreaVal; meanVal; RMSValStd; AreaValStd; meanValStd] ;
dup = any(~diff(buffer, 1, 2), 1) ;
if any(dup)
lId = [dup, false] | [false, dup] ;
RMSVal(lId) = 0 ;
AreaVal(lId) = 0 ;
meanVal(lId) = 0 ;
RMSValStd(lId) = 0 ;
AreaValStd(lId) = NaN ;
meanValStd(lId) = NaN ;
end
If you want to detect invalid data in each array without "sync'ing" invalid locations:
buffer = [RMSVal; AreaVal; meanVal; RMSValStd; AreaValStd; meanValStd] ;
dif = ~diff(buffer, 1, 2) ;
if any(dif(:))
for k = 1 : size(buffer, 1)
if any(dif(k,:))
lId = [dif(k,:), false] | [false, dif(k,:)] ;
if k <= 4
buffer(k,lId) = 0 ;
else
buffer(k,lId) = NaN ;
end
end
end
RMSVal = buffer(1,:) ;
AreaVal = buffer(2,:) ;
meanVal = buffer(3,:) ;
RMSValStd = buffer(4,:) ;
AreaValStd = buffer(5,:) ;
meanValStd = buffer(6,:) ;
end
Chris E. on 19 Jul 2013
Thank you for the comments! I think that the last one you suggested will work for what I need and it is faster! Thanks again, Chris