Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / April 2005

Tip: Looking for answers? Try searching our database.

Cross tabulation - someone please help if you can

Thread view: 
rn29 - 28 Apr 2005 19:23 GMT
Hi,

I need advise re the best data structure to use for representing data
in aggregated form. I am looking to do something like this
       Year 1            Year 2
    number percent    number percent ...

MAJ    66    0.0    61    0.0    ...
GRAD    0    0.0    0    0.0    ...
NOTA    0    0.0    3    0.0    ...
TOTAL    66    100.0    66    100.0    ...

The example shown above is my output from a current program. I will not
include it here because I don't want bring too much focus to the
program itself. The problem is that I can't get the percent values to
come out correctly although the number part is right. I really don't
know what else to do after two days of looking at this code. The
question is, what data structure is best suited to do this type of
work. I tried using a hashtable [] where each hash table in the array
held data for one group. So for the data above I would have five
hashtables in the array each holding Maj, Grad, Nota and Total data
items as keys. The value part is a class that has number and percent
along with some other details.

Any help will be much appreciated. Please let me know if it is helpful
for you to see the code so far.

-Reuben
Ross Bamford - 29 Apr 2005 00:29 GMT
> Hi,
>
[quoted text clipped - 7 lines]
> NOTA    0    0.0    3    0.0    ...
> TOTAL    66    100.0    66    100.0    ...

Am I reading you correctly here? Because from what you're saying above I
would figure something like:

class YearStats
{
 final int maj;
 final int grad;
 final int nota;

 YearStats(int maj, int grad, int nota) {
   this.maj = maj;
   this.grad = grad;
   this.nota = nota;
 }

 public int total() {
   return int+maj+grad;
 }

 public int asPercent(int value) {
   return (total() / 100) * value;
 }    
}

Which you'd then keep in a simple List:

ArrayList<YearStats> years = new ArrayList<YearStats>();
years.add(new YearStats(66,0,0));
years.add(new YearStats(61,0,3));

... etc ...

And then you could print 'em:

for (YearStats year : years) {
 System.out.println("Year "+i+");
 System.out.println("MAJ   " + year.maj+" (" + year.asPercent(maj) +
")");  
 System.out.println("GRAD  "+year.grad+" (" + year.asPercent(grad) +
")");  
 System.out.println("NOTA  "+year.nota+" (" + year.asPercent(nota) +
")");  
 System.out.println("TOTAL "+year.total());  
}

Not sure if that's what you meant?

> Any help will be much appreciated. Please let me know if it is helpful
> for you to see the code so far.
>
> -Reuben

Always :)

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain

rn29 - 29 Apr 2005 01:51 GMT
Thanks!

your thoughts are good but I think I failed to properly communicate the
problem. Now I am forced to post the code and perhaps that will help
see what i am trying to do. The sample table I provided is actually
what the final output should look like except the percent calculation
needs to be right. I am posting here the main method. Everything works
well except the first row output in the percent column all resolve to
100% and while debuging, I have determined that most of the percent
values are not even being innitialized. Where is the problem coming
from?

public static void main(String[] args) throws IOException{
        //read an array of fall cohorts
        File inFile = new File(args[0]);
        ArrayList<FallCohorts> fallcohort = new ArrayList<FallCohorts>();
        try{
            BufferedReader in = new BufferedReader(new FileReader(inFile));
            String line = null;
            while((line = in.readLine()) != null){
                FallCohorts cohort = new FallCohorts();
                cohort.readData(line);
                fallcohort.add(cohort);
            }
            in.close();
        }
        catch(EOFException e){
            e.printStackTrace();
        }
            final String NOT_IN_ATTENDANCE = "NOTA";
            final String GRADUATED = "GRAD";
            final String ENROLLED_SAME_PROGRAM = "SMAJ";
            final String ENROLLED_OTHER_PROGRAM = "OMAJ";
            final String TOTAL = "TOTAL";
            String [] rowNames = new String[5];
            rowNames[0] = ENROLLED_SAME_PROGRAM;
            rowNames[1] = ENROLLED_OTHER_PROGRAM;
            rowNames[2] = GRADUATED;
            rowNames[3] = NOT_IN_ATTENDANCE;
            rowNames[4] = TOTAL;
            Hashtable [] h = new Hashtable[13];

            //initialize array
            for(int i = 0; i < h.length; i++){
                h[i] = new Hashtable();
                h[i].put(ENROLLED_SAME_PROGRAM, new TabulateTerm());
                h[i].put(ENROLLED_OTHER_PROGRAM, new TabulateTerm());
                h[i].put(GRADUATED, new TabulateTerm());
                h[i].put(NOT_IN_ATTENDANCE, new TabulateTerm());
                h[i].put(TOTAL, new TabulateTerm());

                //check keys are innitializing correctly
            //    Enumeration e = h[i].keys();
                //while(e.hasMoreElements()){
                    //System.out.println(i + " " + e.nextElement());
                //}
            }
            //Loop and tabulate

            TabulateTerm row, columnTotal;
            for(FallCohorts f : fallcohort){

                //column 1
                if(f.getCohortStartYear() == f.getYearTerm()){
                    row = (TabulateTerm) h[0].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[0].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber() + 1);
                    columnTotal.setNumber(columnTotal.getNumber() + 1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
                //column 2
                else if((f.getCohortStartYear() + 8) == f.getYearTerm()){
                        row = (TabulateTerm) h[1].get(f.getGroup());
                        columnTotal = (TabulateTerm) h[1].get(TOTAL);
                        row.setTerm(f.getYearTerm());
                        row.setGroup(f.getGroup());
                        row.setNumber(row.getNumber()+1);
                        columnTotal.setNumber(columnTotal.getNumber()+1);
                        row.setPercent(row.getNumber()/columnTotal.getNumber());
                        columnTotal.setPercent(100);
                }
                //column 3
                else if((f.getCohortStartYear()+ 10) == f.getYearTerm()){
                    row = (TabulateTerm) h[2].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[2].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber()+1);
                    columnTotal.setNumber(columnTotal.getNumber()+1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
                //column 4
                else if((f.getCohortStartYear()+ 18) == f.getYearTerm()){
                    row = (TabulateTerm) h[3].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[3].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber()+1);
                    columnTotal.setNumber(columnTotal.getNumber()+1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
                //column 5
                else if((f.getCohortStartYear()+ 20) == f.getYearTerm()){
                    row = (TabulateTerm) h[4].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[4].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber()+1);
                    columnTotal.setNumber(columnTotal.getNumber()+1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
                //column 6
                else if((f.getCohortStartYear()+ 28) == f.getYearTerm()){
                    row = (TabulateTerm) h[5].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[5].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber()+1);
                    columnTotal.setNumber(columnTotal.getNumber()+1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
                //column 7
                else if((f.getCohortStartYear()+ 30) == f.getYearTerm()){
                    row = (TabulateTerm) h[6].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[6].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber()+1);
                    columnTotal.setNumber(columnTotal.getNumber()+1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
                //column 8
                else if((f.getCohortStartYear()+ 38) == f.getYearTerm()){
                    row = (TabulateTerm) h[7].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[7].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber()+1);
                    columnTotal.setNumber(columnTotal.getNumber()+1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
                //column 9
                else if((f.getCohortStartYear()+ 40) == f.getYearTerm()){
                    row = (TabulateTerm) h[8].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[8].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber()+1);
                    columnTotal.setNumber(columnTotal.getNumber()+1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
                //column 10
                else if((f.getCohortStartYear()+ 48) == f.getYearTerm()){
                    row = (TabulateTerm) h[9].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[9].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber()+1);
                    columnTotal.setNumber(columnTotal.getNumber()+1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
                //column 11
                else if((f.getCohortStartYear()+ 50) == f.getYearTerm()){
                    row = (TabulateTerm) h[10].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[10].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber()+1);
                    columnTotal.setNumber(columnTotal.getNumber()+1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
                //column 12
                else if((f.getCohortStartYear()+ 58) == f.getYearTerm()){
                    row = (TabulateTerm) h[11].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[11].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber()+1);
                    columnTotal.setNumber(columnTotal.getNumber()+1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
                //column 13
                else if((f.getCohortStartYear()+ 60) == f.getYearTerm()){
                    row = (TabulateTerm) h[12].get(f.getGroup());
                    columnTotal = (TabulateTerm) h[12].get(TOTAL);
                    row.setTerm(f.getYearTerm());
                    row.setGroup(f.getGroup());
                    row.setNumber(row.getNumber()+1);
                    columnTotal.setNumber(columnTotal.getNumber()+1);
                    row.setPercent(row.getNumber()/columnTotal.getNumber());
                    columnTotal.setPercent(100);
                }
            }
            //print heading row
            for(int i = 0; i < rowNames.length; i++){
                System.out.print(rowNames[i] + "\t");
                //print row data
                for(int j = 0; j < h.length; j++){
                    row = (TabulateTerm)h[j].get(rowNames[i]);
                    System.out.print(row.toString());
                }
                System.out.println();
            }
    }
Ross Bamford - 29 Apr 2005 03:26 GMT
> Thanks!
>
[quoted text clipped - 7 lines]
> values are not even being innitialized. Where is the problem coming
> from?

Well, looking through that nothing jumps out immediately. It's a bit
unconventional but I can't think of a reason it shouldn't work. Where to
go next:

TabulateTerm - is that your own class? It seems to me the most likely
place to start. How/where is the percentage actually calculated? From
what (variables)? Where do they get their values from? I assume you're
using both the column and the row - are you sure they're the correct
(paired) column and row?

Check your code is executed: A simple System.out.println within the
if/elseif construct(s) might help to trace things. Perhaps the values
aren't initialized because none of the ifs match?

Another idea is to println() your Hashtable.toString() once it's
populated, to check it's laid out how you expect.

Hope that helps,
Ross

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain

rn29 - 29 Apr 2005 14:21 GMT
Well, unconventional? I have no doubt, but I am open to conventional
suggestions of how I might do this. Thanks for your suggestion.

It turns out, as it always does that I was creating my own woes. the
setPercent method of the TabulateTerm class expects a double whereas I
was passing the result of an int divided by an int. In most other
languages that I know, c++ for example, you would get automatic
conversion. The trouble with this operation in java is that no warnings
or errors were being generated but instead it simply throws the result
away - I think. I will have to spend some time to investigate exactly
what it was doing.

Thanks again,

-Reuben
Ross Bamford - 29 Apr 2005 19:02 GMT
> Well, unconventional? I have no doubt, but I am open to conventional
> suggestions of how I might do this. Thanks for your suggestion.
[quoted text clipped - 11 lines]
>
> -Reuben

Glad you're closer to a solution :) And as for unconventional, whats the
box for if you can't think outside it - big believer myself :)

You shouldn't ever get a result thrown away without so much as a warning
- Similar rules to c++ do apply in Java (although of course they differ
in many details) but basically, primitive conversion is carried out
explicitly where it doesn't involve loss of precision, but where an
implicit conversion would result in such a loss, a compile-time error is
generated.

You might try inserting a couple of temporary S.o.println() calls, to
sanity check the two parameters you are dividing before you divide, and
then again inside the method when you first see the result as a double.
I'd guess you'll find the original arguments are unset. Or of course set
a watch if debugging be your pleasure.

Cheers,
Ross

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.