/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * CrossTabulationDialog.java
 *
 * Created on Feb 5, 2010, 11:05:21 AM
 */

package org.statcato.dialogs.stat.multinomial;

import org.statcato.*;
import org.statcato.spreadsheet.Cell;
import org.statcato.utils.HelperFunctions;
import org.statcato.utils.CategoryCounter;
import org.statcato.statistics.inferential.*;
import org.statcato.spreadsheet.Spreadsheet;

import java.util.Vector;

/**
 * A dialog for cross tabulation and Chi-square test.
 * Allows user to row and column labels in two columns and optionally
 * the frequencies corresponding to the observations.  Generates a table
 * of counts and percents.  Provides the option of performing a Chi-square
 * test on the contingency table generated.
 *
 * @author  Margaret Yau
 * @version %I%, %G%
 * @see org.statcato.statistics.inferential.CrossTabulation
 * @since 1.0
 */
public class CrossTabulationDialog extends StatcatoDialog {

    /** Creates new form CrossTabulationDialog */
    public CrossTabulationDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();

        app = (Statcato)parent;
        ParentSpreadsheet = app.getSpreadsheet();

        customInitComponents();

        setHelpFile("stat-cross-tabulation");
        name = "Cross Tabulation and Chi-Square Test";
        description = "For performing cross tabulation and the Chi-square Test for "
                + "two variables.";
        helpStrings.add("Provide row and column labels in two separate columns.  " +
                "Select the columns in the corresponding drop-down menus.");
        helpStrings.add("Provide the frequencies in a column (optional).");
        helpStrings.add("Select if a Chi-square test should be performed" +
                " and provide the significance level.");
        helpStrings.add("Select whether to store the results in a new datasheet.");
    }

    private void customInitComponents() {
        ParentSpreadsheet.populateComboBox(FreqComboBox);
        ParentSpreadsheet.populateComboBox(RowComboBox);
        ParentSpreadsheet.populateComboBox(ColComboBox);
        getRootPane().setDefaultButton(OKButton);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // //GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        ColComboBox = new javax.swing.JComboBox();
        RowComboBox = new javax.swing.JComboBox();
        FreqComboBox = new javax.swing.JComboBox();
        CancelButton = new javax.swing.JButton();
        OKButton = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        jLabel6 = new javax.swing.JLabel();
        SigTextField = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        ChiSquareCheckBox = new javax.swing.JCheckBox();
        jPanel3 = new javax.swing.JPanel();
        StoreCheckBox = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Cross Tabulation");

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Inputs"));

        jLabel3.setText("Column:");

        jLabel2.setText("Row:");

        jLabel1.setText("Frequency:
(optional)\n"); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(FreqComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(26, 26, 26) .addComponent(jLabel3)) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(39, 39, 39) .addComponent(jLabel2))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(ColComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(RowComboBox, 0, 121, Short.MAX_VALUE)))) .addContainerGap(52, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(RowComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel2)) .addGap(27, 27, 27) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(ColComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel3)) .addGap(26, 26, 26) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(FreqComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); CancelButton.setText("Cancel"); CancelButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { CancelButtonActionPerformed(evt); } }); OKButton.setText("OK"); OKButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { OKButtonActionPerformed(evt); } }); jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Chi-Square Test")); jLabel6.setText("Significance level:"); SigTextField.setText("0.05"); jLabel4.setText("0 - 1.00 (e.g. 0.05)"); ChiSquareCheckBox.setSelected(true); ChiSquareCheckBox.setText("Perform Chi-square test"); ChiSquareCheckBox.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { ChiSquareCheckBoxStateChanged(evt); } }); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(ChiSquareCheckBox) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(jLabel6) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(SigTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel4)))) .addContainerGap(47, Short.MAX_VALUE)) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() .addContainerGap() .addComponent(ChiSquareCheckBox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(SigTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel6)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel4) .addContainerGap()) ); jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Results")); StoreCheckBox.setText("Store table in a new datasheet"); StoreCheckBox.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { StoreCheckBoxStateChanged(evt); } }); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() .addComponent(StoreCheckBox) .addGap(63, 63, 63)) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(StoreCheckBox) .addContainerGap(29, Short.MAX_VALUE)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addGap(86, 86, 86) .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(CancelButton)) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(40, 40, 40) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(CancelButton) .addComponent(OKButton))) ); pack(); }//
//GEN-END:initComponents /** * Updates elements on the dialog so that they have the most * current values. Called by {@link #setVisible} to make * sure the dialog displays current values when made visible again. * * @see #setVisible(boolean) */ @Override public void updateElements() { updateComboBox(FreqComboBox); updateComboBox(RowComboBox); updateComboBox(ColComboBox); } private void OKButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_OKButtonActionPerformed app.compoundEdit = new DialogEdit("cross tabulation"); String heading = "Cross Tabulation and Chi-Square"; String text = ""; boolean hasFrequency = true; Vector ResponseVector = null; // frequency column String columnLabel = FreqComboBox.getSelectedItem().toString(); if (columnLabel.equals("")) { // no frequency hasFrequency = false; } else { text += "frequencies in " + columnLabel + ", "; hasFrequency = true; int selectedXColumn = ParentSpreadsheet.parseColumnNumber(columnLabel); Vector StrColumnVector = ParentSpreadsheet.getColumn(selectedXColumn); StrColumnVector = HelperFunctions.removeEndingEmptyCells(StrColumnVector); // get frequency column of doubles ResponseVector = HelperFunctions.ConvertInputVectorToDoubles(StrColumnVector); if (ResponseVector == null) { app.showErrorDialog("Invalid frequency column " + columnLabel + ": all data must be numbers."); return; } } // row labels column String rowLabel = RowComboBox.getSelectedItem().toString(); text += "rows in " + rowLabel; if (rowLabel.equals("")) { // no row variable app.showErrorDialog("Select the row factor variable."); return; } int rowColumn = ParentSpreadsheet.parseColumnNumber(rowLabel); Vector RowVector = ParentSpreadsheet.getColumn(rowColumn); RowVector = HelperFunctions.removeEndingEmptyCells(RowVector); if (hasFrequency && RowVector.size() < ResponseVector.size()) { app.showErrorDialog("missing row factor label(s)"); return; } // column labels column String colLabel = ColComboBox.getSelectedItem().toString(); text += ", columns in " + colLabel + "
"; if (colLabel.equals("")) { // no col variable app.showErrorDialog("Select the column factor variable."); return; } int colColumn = ParentSpreadsheet.parseColumnNumber(colLabel); Vector ColVector = ParentSpreadsheet.getColumn(colColumn); ColVector = HelperFunctions.removeEndingEmptyCells(ColVector); if (hasFrequency && ColVector.size() < ResponseVector.size()) { app.showErrorDialog("missing column factor label(s)"); return; } if (RowVector.size() != ColVector.size()) { app.showErrorDialog("The number of row labels and the number of" + " column labels should be the same."); return; } if (hasFrequency && ResponseVector.size() != RowVector.size()) { app.showErrorDialog("The number of frequencies and row/column " + "labels should be the same."); return; } // set up category counters for row and column CategoryCounter rowCategoryCounter = new CategoryCounter(); for (int i = 0; i < RowVector.size(); ++i) rowCategoryCounter.addCategory(RowVector.elementAt(i).getContents()); CategoryCounter colCategoryCounter = new CategoryCounter(); for (int i = 0; i < ColVector.size(); ++i) colCategoryCounter.addCategory(ColVector.elementAt(i).getContents()); CrossTabulation ct = new CrossTabulation(rowCategoryCounter.getSize(), colCategoryCounter.getSize()); // add observations to CrossTabulation object for (int i = 0; i < RowVector.size(); ++i) { double freq = 1; if (hasFrequency) { if (ResponseVector.elementAt(i) != null) freq = ResponseVector.elementAt(i).doubleValue(); else freq = 0; } Cell row = RowVector.elementAt(i); Cell col = ColVector.elementAt(i); if (row == null || col == null || row.getContents().equals("") || col.getContents().equals("")) { app.showErrorDialog("Missing row or column label for data " + "at row " + (i+1)); return; } ct.addObservation(rowCategoryCounter.getIndex(row.getContents()), colCategoryCounter.getIndex(col.getContents()), freq); } Vector rowCategories = rowCategoryCounter.getCategories(); Vector colCategories = colCategoryCounter.getCategories(); // vectors for storing table Vector> resultVectors = new Vector>(); for (int j = 0; j < rowCategories.size()+1; ++j) { resultVectors.addElement(new Vector()); } Vector varNameVector = new Vector(); varNameVector.addElement(""); // build cross tabulation table text += ""; // print column headings text += ""; for (int j = 0; j < colCategories.size(); ++j) { text += ""; varNameVector.addElement(colCategories.elementAt(j)); } varNameVector.addElement("All"); text += ""; for (int i = 0; i < rowCategories.size(); ++i) { String rowCategory = rowCategories.elementAt(i); int rowIndex = rowCategoryCounter.getIndex(rowCategory); text += ""; resultVectors.elementAt(i).addElement(rowCategory); for (int j = 0; j < colCategories.size(); ++j) { String colCategory = colCategories.elementAt(j); int colIndex = colCategoryCounter.getIndex(colCategory); double f = ct.getFrequency(rowIndex, colIndex); double percent = ct.getPercent(rowIndex, colIndex); text += ""; resultVectors.elementAt(i).addElement(f + ""); } double rowSum = ct.getRowSum(rowIndex); text += ""; text += ""; resultVectors.elementAt(i).addElement(rowSum + ""); } text += ""; resultVectors.elementAt(rowCategories.size()).addElement("All"); for (int j = 0; j < colCategories.size(); ++j) { String colCategory = colCategories.elementAt(j); int colIndex = colCategoryCounter.getIndex(colCategory); double colSum = ct.getColumnSum(colIndex); text += ""; resultVectors.elementAt(rowCategories.size()).addElement(colSum + ""); } double totalSum = ct.getTotalSum(); text += ""; text += "
 " + colCategories.elementAt(j) +"All
" + rowCategory + "" + f + " (" + HelperFunctions.formatFloat(percent * 100, 2) + "%)" + rowSum + " (" + HelperFunctions.formatFloat(ct.getRowSumPercent(rowIndex) * 100, 2) + "%)
All" + colSum + " (" + HelperFunctions.formatFloat(ct.getColumnSumPercent(colIndex) * 100, 2) + "%)" + totalSum + " (100.00%)
"; text += "
"; resultVectors.elementAt(rowCategories.size()).addElement(totalSum + ""); if (ChiSquareCheckBox.isSelected()) { double significance; try { significance = Double.parseDouble(SigTextField.getText()); } catch (NumberFormatException e) { app.showErrorDialog("Enter a number between 0 and 1 for the significance level."); return; } if (significance <= 0 || significance >= 1) { app.showErrorDialog("Enter a number between 0 and 1 for the confidence level."); return; } ct.computeChiSquare(); ContingencyTable table = ct.getContingencyTable(); text += "Chi-Square Test
"; text += ""; text += "" + "" + ""; text += ""; text += "
Significance LevelDOFΧ2Critical valuep-Value
" + HelperFunctions.formatFloat(significance, 2) + "" + table.DOF() + "" + HelperFunctions.formatFloat(table.testStatistics(), 4) + "" + HelperFunctions.formatFloat(table.criticalValue(significance), 4) + "" + HelperFunctions.formatFloat(table.pValue(), 4) + "
"; } if (StoreCheckBox.isSelected()) { // store table in new worksheet Spreadsheet ThisSpreadsheet = new Spreadsheet(app); app.getDatasheetTabbedPane().addDatasheet(ThisSpreadsheet); ThisSpreadsheet.setData(resultVectors); ThisSpreadsheet.setVariablesRow(varNameVector); app.getDatasheetTabbedPane().setCurrentTabTitle("CrossTabulation*"); } app.addLogParagraph(heading, text); app.compoundEdit.end(); app.addCompoundEdit(app.compoundEdit); setVisible(false); }//GEN-LAST:event_OKButtonActionPerformed private void CancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CancelButtonActionPerformed setVisible(false); }//GEN-LAST:event_CancelButtonActionPerformed private void ChiSquareCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_ChiSquareCheckBoxStateChanged if (ChiSquareCheckBox.isSelected()) SigTextField.setEnabled(true); else SigTextField.setEnabled(false); }//GEN-LAST:event_ChiSquareCheckBoxStateChanged private void StoreCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_StoreCheckBoxStateChanged }//GEN-LAST:event_StoreCheckBoxStateChanged // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton CancelButton; private javax.swing.JCheckBox ChiSquareCheckBox; private javax.swing.JComboBox ColComboBox; private javax.swing.JComboBox FreqComboBox; private javax.swing.JButton OKButton; private javax.swing.JComboBox RowComboBox; private javax.swing.JTextField SigTextField; private javax.swing.JCheckBox StoreCheckBox; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel6; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; // End of variables declaration//GEN-END:variables }

Ads help maintain this website.