/*
* 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 += "" + colCategories.elementAt(j) +" ";
varNameVector.addElement(colCategories.elementAt(j));
}
varNameVector.addElement("All");
text += "All ";
for (int i = 0; i < rowCategories.size(); ++i) {
String rowCategory = rowCategories.elementAt(i);
int rowIndex = rowCategoryCounter.getIndex(rowCategory);
text += "" + rowCategory + " ";
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 += "" + f + " (" +
HelperFunctions.formatFloat(percent * 100, 2) +
"%) ";
resultVectors.elementAt(i).addElement(f + "");
}
double rowSum = ct.getRowSum(rowIndex);
text += "" + rowSum + " (" +
HelperFunctions.formatFloat(ct.getRowSumPercent(rowIndex) * 100, 2)
+ "%) ";
text += " ";
resultVectors.elementAt(i).addElement(rowSum + "");
}
text += "All ";
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 += "" +
colSum + " (" +
HelperFunctions.formatFloat(ct.getColumnSumPercent(colIndex) * 100, 2)
+ "%) ";
resultVectors.elementAt(rowCategories.size()).addElement(colSum + "");
}
double totalSum = ct.getTotalSum();
text += "" + totalSum + " (100.00%) ";
text += " ";
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 += "Significance Level DOF " +
"Χ2 Critical value " +
"p-Value ";
text += "" + HelperFunctions.formatFloat(significance, 2)
+ " " + table.DOF() + " " +
HelperFunctions.formatFloat(table.testStatistics(), 4)
+ " " +
HelperFunctions.formatFloat(table.criticalValue(significance), 4)
+ " " +
HelperFunctions.formatFloat(table.pValue(), 4) + " ";
text += " ";
}
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.