Get new variable based on a condition

1 Ansicht (letzte 30 Tage)
Maria
Maria am 11 Aug. 2014
Bearbeitet: Andrei Bobrov am 12 Aug. 2014
I have a double variable with 3 columns and 60000 rows, sorted by c2 and then by c1. For example:
c1 c2 c3
M=[2008 1 1
2009 1 2
2010 1 34
1996 12 7
1997 12 *11*
1998 12 *5*
1999 12 *5*
2000 12 4
1998 13 14
1999 13 1 ] %in this case I don't have the value for the two previous years
For each different c2, and if c1 is equal to 1999 I am trying to have a new variable P, with the year, with c2 and with the sum of the values in c3 from that year (1999 )and the two previous years/rows (1998 and 1997).
In this example my output would be:
P=[ 1999 12 21] %(5 + 5 + 11)
Thanks
  3 Kommentare
Maria
Maria am 11 Aug. 2014
Exactly
Maria
Maria am 11 Aug. 2014
Because it is possible that it happens.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Image Analyst
Image Analyst am 11 Aug. 2014
Try this and see if it's what you want:
clc;
workspace;
M=[2008 1 1
2009 1 2
2010 1 34
1996 12 7
1997 12 11
1998 12 5
1999 12 5
2000 12 4
1998 13 14
1999 13 1 ]
uniqueC2 = unique(M(:,2))
P = [0,0,0];
counter = 1;
for k = 1 : length(uniqueC2)
% Find rows for this c2.
thisC2 = M(:,2) == uniqueC2(k);
% Find rows where c1 == 1999
validRows = M(:,1) == 1999;
% AND them
validRows = validRows & thisC2;
if any(validRows)
% This c2 has at least one year with 1999
% Find out what row it's in.
the1999Row = find(validRows);
% Sum this row only if there are at least two prior rows
% with the same value of C2.
if thisC2(the1999Row-1) && thisC2(the1999Row-2)
% Prior 2 rows also belongs to this c2.
theSum = M(the1999Row, 3) + M(the1999Row - 1, 3) + M(the1999Row - 2, 3);
P(counter, :) = [1999, uniqueC2(k), theSum];
counter = counter + 1;
end
end
end
% Print to command window:
P
It's easy to understand and fast. If you want something more compact, but probably harder to understand, someone will probably post a one-liner. But this gives exactly the output you asked for.
  1 Kommentar
Maria
Maria am 12 Aug. 2014
Yes it does! It gives me exactly the output I want! It is a long code, but it's fast so it's perfect. Thank you very much.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (2)

Azzi Abdelmalek
Azzi Abdelmalek am 12 Aug. 2014
Bearbeitet: Azzi Abdelmalek am 12 Aug. 2014
M=[2008 1 1
2009 1 2
2010 1 34
1996 12 7
1997 12 11
1998 12 5
1999 12 5
2000 12 4
1998 13 14
1999 13 1 ]
c4=ismember(M(:,1),1997:1999);
[ii,jj,kk]=unique(M(:,2),'stable');
b=accumarray(kk,M(:,3).*c4);
out=[1999*ones(numel(jj),1) ii b];
idx=accumarray(kk,c4)==3;
out=out(idx,:)

Andrei Bobrov
Andrei Bobrov am 12 Aug. 2014
Bearbeitet: Andrei Bobrov am 12 Aug. 2014
M=[2008 1 1
2009 1 2
2010 1 34
1996 12 7
1997 12 11
1998 12 5
1999 12 5
2000 12 4
1997 13 100
1998 13 14
1999 13 1
1998 14 3
1999 14 6];
[l0,ii] = ismember(M(:,1),1997:1999);
T = accumarray([ii(l0),M(l0,2)],M(l0,3),[],[],nan);
i1 = find(all(~isnan(T))).';
s = sum(T).';
out = [1999*ones(numel(i1),1), i1, s(i1)];
or with for..end loop
u = unique(M(:,2));
out = zeros(numel(u),3);
for i1 = 1:numel(u)
M1 = M(u(i1) == M(:,2),:);
t0 = ismember(M1(:,1),1997:1999);
if nnz(t0) == 3
out(i1,:) = [1999, u(i1), sum(M1(t0,3))];
end
end
out = out(any(out,2),:);

Tags

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by