Matlab Date Sorting Program, need help

edited April 2010 in Science & Tech
Hello, I'm currently trying to write a program which sorts birth dates imported from a text file, in descending order. The data is imported into a matrix of 100 rows and 3 columns; column 1 being the year(yyyy), column 2 being the month(mm), and column 3 being the day(dd). I am able to sort any of the 3 and reference the location of each element so I can swap the rows of each column, but I'm unable to figure out the problem of also sorting the other two columns without screwing up the order of the first. My main issue is that once I get the Year column sorted, the Month and Day columns follow their location just fine, but on elements of the same year, the month and day order are not in proper descending order.

Ex:

Year Month Day
2006 02 05
2006 02 11
2002 05 19
2000 02 18
2000 12 25
2000 10 12
etc...

Comments

  • shwaipshwaip bluffin' with my muffin Icrontian
    edited April 2010
    what have you tried so far? If we could see your code we could give you some pointers.
  • edited April 2010
    I'm currently using a 'bubble' sort function (yes, I know about the built in sort function), but just can't quite figure out how to implement the other two columns without affecting the order of everything else.
    function [y] = DateSort(x) % function definition line
    % H1: Sorts a vector into descending order using a BubbleSort
    % Input Arguments:
    % x = vector
    % Output Arguments:
    % y = vector x sorted in descending order
    
    n = length(x); % compute the number of elements in x
    
    sorted = 0; % a flag varaible used to determine if the vector is fully 
                % sorted. sorted = 0 if not fully sorted, = 1 if fully sorted.
                
    passes = 0; % 0 passes completed at the start
    
    % while loop that continues to make passes through x until it is fully
    % sorted.
    while (~sorted)
        sorted = 1; % Assumes x is fully sorted at the start of each pass
        passes = passes + 1; % Add one to the number of passes
        
        % On each pass through vector x the for loop starts with the first
        % element and continues until the (n-passes) element. After the first
        % pass the smallest value in x will fall to the last element therefore
        % on the second pass there is no need to check to see if the last value
        % is in the correct order. After each subsequent pass the x(n-passes:n)
        % elements are in the correct order. This is why the for loop limits go
        % from 1 to (n-passes).
        for j = 1:n-passes
            if x(j) < x(j+1); % Compares the current element x(j) with the next
                              % element x(j+1).
                temp = x(j);  % Stores the current element in a temp memory location.
                x(j) = x(j+1); % Stores the next value into the current value.
                x(j+1) = temp; % Stores the original current value into the
                               % next value.
                sorted = 0; % Sets sorted to 0 to indicate that an out of order
                            % element was found. This will cause the while loop
                            % to make another pass through x.
            end
        end
    end
    
    y = x; % returns the sorted vector
    

    As for the code, I don't really have much saved at the moment, it's mostly been trial and error in the command window.
    % load function used to import data from a text file
    BDayData = load('Data_11_2.txt');
    % Extracts the data from each column of BDayData
    YearData = BDayData(:,1);
    MonthData = BDayData(:,2);
    DayData = BDayData(:,3);
    
    >> [SortedData,OrigRows]=sort(BDayData(:,1),1,'descend');
    >> BDayMat=BDayData(OrigRows,:)
    BDayMat =
            2006           2           5
            2006           2          11
            2002           5          19
            2000           2          18
            2000          12          25
            2000          10          12
            1998           2           3
            1996          11          13
            1996           7          12
            1996           6           2
            1995           7          29
            1993           1          18
            1993           3          21
            1991          11           5
            1990           2          14
            1990           6          14
            1989           4          13
            1989           8          14
            1989           4          14
            1989           7          23
            1988           6          11
            1988           2           8
            1987           8          13
            1987          11          21
            1987           9          15
            1987           8          31
            1987           3          16
            1986           7           2
            1986           7           7
            1985           2           8
            1985           7           7
            1985          11          23
            1985           7          23
            1984          11          13
            1984          11          24
            1984           5          29
            1984           5          17
            1984           7          23
            1984           3          12
            1984           7          30
            1984           4          15
            1983           6          11
            1983           3           4
            1983          11          25
            1982           8          31
            1982           4           2
            1982          11          18
            1982           8          12
            1982           6          12
            1981          10          28
            1981           5          13
            1981           6          25
            1981          11          12
            1981           9          29
            1980           5          11
            1980          12          11
            1980           6          26
            1980           5          25
            1979           7           2
            1979          11           6
            1978          11          24
            1978           4          18
            1978           9          29
            1978           7          15
            1978           6          25
            1977          11          26
            1975           1          27
            1975           9          14
            1974           9          28
            1974           1          14
            1974           4          28
            1974           4           1
            1974          10           8
            1974           9          30
            1973           9          18
            1973           4          20
            1973           6          19
            1973           1           9
            1973           5          17
            1972          10          12
            1972          11          26
            1972           8          31
            1971          12           8
            1971           6          29
            1970          10           9
            1970           4           7
            1970           5          18
            1970           4           4
            1968           6           1
            1968           3          14
            1966           6           3
            1965           7          16
            1965           5          23
            1964           3           9
            1964           9           4
            1961           5          13
            1960           1          30
            1959           4          25
            1959           1          10
            1957           2          27
    >>
    

    So yeah, I'm pretty much stuck on trying to keep the year column in the same order, while just re-sorting the months and days within each section of years.
  • shwaipshwaip bluffin' with my muffin Icrontian
    edited April 2010
    use the datenum function to convert the yyyy/mm/dd data into serial date numbers, then you can use whatever sort function you'd like.
  • edited April 2010
    Thanks, I completely forgot that function existed.
  • edited April 2010
    Actually, I'm having another issue with this problem. Now that everything is sorted, I'm using another user-defined function to compute the age based on the dates given and the current date entered by the user. If anyone could help with fixing the error I receive, I'd greatly appreciate it. I've tried a bunch of different things, with no luck so far.

    Here is my function: age
    function [AgeVector] = age(BirthDates,year,month,day) % function definition
    % H1: Determines the age for birth dates given the current year,month,day
    % Input Arguments:
    % BirthDates = matrix of birth dates with the following columns: 4 digit
    % year, 2 digit month, 2 digit day
    % year is the current year
    % month is the current month
    % day is the current day
    % Output Arguments:
    % AgeVector = an integer vector that contains the age for each birth date
    
    % Memory has been preallocated for AgeVector, to increase speed
    AgeVector = zeros;
    
    % A for loop is used to fill the values of AgeVector
    [COLOR="Blue"]for[/COLOR] n=1:1:size(BirthDates,1)
    
        % an if-elseif construct is used to determine whether the current month
        % or day is less than that of the BirthDates matrix.
        [COLOR="blue"]if[/COLOR] (month < BirthDates(:,2))
            % Subtracts one to account for that date having not yet passed
            AgeVector(n) = ((year-BirthDates(:,1))-1);
        [COLOR="blue"]elseif[/COLOR] ((month == BirthDates(:,2)) && (day < BirthDates(:,3)))
            AgeVector(n) = ((year-BirthDates(:,1))-1);
        [COLOR="blue"]else[/COLOR]
            AgeVector(n) = year - BirthDates(:,1);
        [COLOR="blue"]end[/COLOR]
    
    [COLOR="blue"]end[/COLOR]
    

    Some of the code from my program:
    % Asks the user to input values for the year, month, and day
    Year = input('Please enter the current 4 digit year (yyyy) : ');
    Month = input('Please enter the current 2 digit month (mm)  : ');
    Day = input('Please enter the current 2 digit day   (dd)  : ');
    
    % load function used to import data from a text file
    BDayData = load('Data_11_2.txt');
    
    % The datenum function is used to change the dates listed into the date
    % number associated with them. This will allow us to easily sort the dates.
    TempData = datenum(BDayData);
    % The DateSort() function is used to sort the date numbers in ascending
    % order.
    SortedData = DateSort(TempData);
    % The datevec function outputs the values from the sorted data in vector
    % form.
    [SortedYears,SortedMonths,SortedDays] = datevec(SortedData);
    % The three sorted vectors are appended together to create a sorted matrix
    SortedDates = [SortedYears, SortedMonths, SortedDays];
    % The age() function is used to compute the age based on the birthdate and
    % current date entered.
    Ages = age(SortedDates,Year,Month,Day)
    

    And the error I receive after I run:
    Please enter the current 4 digit year (yyyy) : 2010
    Please enter the current 2 digit month (mm)  : 04
    Please enter the current 2 digit day   (dd)  : 27
    [COLOR="Red"]??? Operands to the || and && operators must be convertible to logical scalar values.
    
    Error in ==> age at 23
        elseif ((month == BirthDates(:,2)) && (day < BirthDates(:,3)))
    
    Error in ==> Program_11_2 at 50
    Ages = age(SortedDates,Year,Month,Day)[/COLOR]
     
    >>
    

    Once again, any feedback is appreciated,
  • shwaipshwaip bluffin' with my muffin Icrontian
    edited April 2010
    as a quick suggestion:

    you're looping over the length of birthdates with the variable n, but you're not using n to index either BirthDates(:,2) or Birthdates(:,3). you might want them to be BirthDates(n,2) and 3.

    If that's not the issue, i'll take a closer look.
  • edited April 2010
    I just noticed the exact same thing! The lack of sleep is making me miss minor details like that
Sign In or Register to comment.