Add.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 11k
Category:

Windows Develop

Development Platform:

Java

  1. /*
  2.  *    This program is free software; you can redistribute it and/or modify
  3.  *    it under the terms of the GNU General Public License as published by
  4.  *    the Free Software Foundation; either version 2 of the License, or
  5.  *    (at your option) any later version.
  6.  *
  7.  *    This program is distributed in the hope that it will be useful,
  8.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  *    GNU General Public License for more details.
  11.  *
  12.  *    You should have received a copy of the GNU General Public License
  13.  *    along with this program; if not, write to the Free Software
  14.  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15.  */
  16. /*
  17.  *    Add.java
  18.  *    Copyright (C) 1999 Len Trigg
  19.  *
  20.  */
  21. package weka.filters.unsupervised.attribute;
  22. import weka.filters.*;
  23. import java.io.*;
  24. import java.util.*;
  25. import weka.core.*;
  26. /** 
  27.  * An instance filter that adds a new attribute to the dataset. 
  28.  * The new attribute contains all missing values.<p>
  29.  *
  30.  * Valid filter-specific options are:<p>
  31.  *
  32.  * -C index <br>
  33.  * Specify where to insert the column. First and last are valid indexes.
  34.  * (default last)<p>
  35.  *
  36.  * -L label1,label2,...<br>
  37.  * Create nominal attribute with the given labels
  38.  * (default numeric attribute)<p>
  39.  *
  40.  * -N name<br>
  41.  * Name of the new attribute. (default = 'Unnamed')<p>
  42.  *
  43.  * @author Len Trigg (trigg@cs.waikato.ac.nz)
  44.  * @version $Revision: 1.1 $
  45.  */
  46. public class Add extends Filter implements UnsupervisedFilter,
  47.    StreamableFilter, OptionHandler {
  48.   /** Record the type of attribute to insert */
  49.   protected int m_AttributeType = Attribute.NUMERIC;
  50.   /** The name for the new attribute */
  51.   protected String m_Name = "unnamed";
  52.   /** The location to insert the new attribute */
  53.   protected int m_Insert = -1;
  54.   /** The list of labels for nominal attribute */
  55.   protected FastVector m_Labels = new FastVector(5);
  56.   /**
  57.    * Returns a string describing this filter
  58.    *
  59.    * @return a description of the filter suitable for
  60.    * displaying in the explorer/experimenter gui
  61.    */
  62.   public String globalInfo() {
  63.     return "An instance filter that adds a new attribute to the dataset."
  64.       + " The new attribute will contain all missing values.";
  65.   }
  66.   /**
  67.    * Returns an enumeration describing the available options.
  68.    *
  69.    * @return an enumeration of all the available options.
  70.    */
  71.   public Enumeration listOptions() {
  72.     Vector newVector = new Vector(3);
  73.     newVector.addElement(new Option(
  74.               "tSpecify where to insert the column. First and lastn"
  75.       +"tare valid indexes.(default last)",
  76.               "C", 1, "-C <index>"));
  77.     newVector.addElement(new Option(
  78.       "tCreate nominal attribute with given labelsn"
  79.       +"t(default numeric attribute)",
  80.               "L", 1, "-L <label1,label2,...>"));
  81.     newVector.addElement(new Option(
  82.               "tName of the new attribute.n"
  83.               +"t(default = 'Unnamed')",
  84.               "N", 1,"-N <name>"));
  85.     return newVector.elements();
  86.   }
  87.   /**
  88.    * Parses a list of options for this object. Valid options are:<p>
  89.    *
  90.    * -C index <br>
  91.    * Specify where to insert the column. First and last are valid indexes.
  92.    * (default last)<p>
  93.    *
  94.    * -L label1,label2,...<br>
  95.    * Create nominal attribute with the given labels
  96.    * (default numeric attribute)<p>
  97.    *
  98.    * -N name<br>
  99.    * Name of the new attribute. (default = 'Unnamed')<p>
  100.    *
  101.    * @param options the list of options as an array of strings
  102.    * @exception Exception if an option is not supported
  103.    */
  104.   public void setOptions(String[] options) throws Exception {
  105.     
  106.     String insertString = Utils.getOption('C', options);
  107.     if (insertString.length() != 0) {
  108.       if (insertString.toLowerCase().equals("last")) {
  109. setAttributeIndex(-1);
  110.       } else if (insertString.toLowerCase().equals("first")) {
  111. setAttributeIndex(0);
  112.       } else {
  113. setAttributeIndex(Integer.parseInt(insertString) - 1); 
  114.       }
  115.     }
  116.     setNominalLabels(Utils.getOption('L', options));
  117.     setAttributeName(Utils.getOption('N', options));
  118.     if (getInputFormat() != null) {
  119.       setInputFormat(getInputFormat());
  120.     }
  121.   }
  122.   /**
  123.    * Gets the current settings of the filter.
  124.    *
  125.    * @return an array of strings suitable for passing to setOptions
  126.    */
  127.   public String [] getOptions() {
  128.     String [] options = new String [6];
  129.     int current = 0;
  130.     options[current++] = "-N"; options[current++] = getAttributeName();
  131.     if (m_AttributeType == Attribute.NOMINAL) {
  132.       options[current++] = "-L"; options[current++] = getNominalLabels();
  133.     }
  134.     options[current++] = "-C";
  135.     options[current++] = "" + (getAttributeIndex() + 1);
  136.     while (current < options.length) {
  137.       options[current++] = "";
  138.     }
  139.     return options;
  140.   }
  141.   /**
  142.    * Sets the format of the input instances.
  143.    *
  144.    * @param instanceInfo an Instances object containing the input instance
  145.    * structure (any instances contained in the object are ignored - only the
  146.    * structure is required).
  147.    * @return true if the outputFormat may be collected immediately
  148.    * @exception Exception if the format couldn't be set successfully
  149.    */
  150.   public boolean setInputFormat(Instances instanceInfo) throws Exception {
  151.     super.setInputFormat(instanceInfo);
  152.     Instances outputFormat = new Instances(instanceInfo, 0);
  153.     Attribute newAttribute = null;
  154.     switch (m_AttributeType) {
  155.     case Attribute.NUMERIC:
  156.       newAttribute = new Attribute(m_Name);
  157.       break;
  158.     case Attribute.NOMINAL:
  159.       newAttribute = new Attribute(m_Name, m_Labels);
  160.       break;
  161.     default:
  162.       throw new Error("Unknown attribute type in Add");
  163.     }
  164.     if ((m_Insert < 0) || (m_Insert > getInputFormat().numAttributes())) {
  165.       m_Insert = getInputFormat().numAttributes();
  166.     }
  167.     outputFormat.insertAttributeAt(newAttribute, m_Insert);
  168.     setOutputFormat(outputFormat);
  169.     return true;
  170.   }
  171.   /**
  172.    * Input an instance for filtering. Ordinarily the instance is processed
  173.    * and made available for output immediately. Some filters require all
  174.    * instances be read before producing output.
  175.    *
  176.    * @param instance the input instance
  177.    * @return true if the filtered instance may now be
  178.    * collected with output().
  179.    * @exception IllegalStateException if no input format has been defined.
  180.    */
  181.   public boolean input(Instance instance) {
  182.     if (getInputFormat() == null) {
  183.       throw new IllegalStateException("No input instance format defined");
  184.     }
  185.     if (m_NewBatch) {
  186.       resetQueue();
  187.       m_NewBatch = false;
  188.     }
  189.     Instance inst = (Instance)instance.copy();
  190.     // First copy string values from input to output
  191.     // Will break if the attribute being created is of type STRING (currently
  192.     // Add only adds NOMINAL or NUMERIC types)
  193.     copyStringValues(inst, true, inst.dataset(), getOutputFormat());
  194.     // Insert the new attribute and reassign to output
  195.     inst.setDataset(null);
  196.     inst.insertAttributeAt(m_Insert);
  197.     inst.setDataset(getOutputFormat());
  198.     push(inst);
  199.     return true;
  200.   }
  201.   /**
  202.    * Returns the tip text for this property
  203.    *
  204.    * @return tip text for this property suitable for
  205.    * displaying in the explorer/experimenter gui
  206.    */
  207.   public String attributeNameTipText() {
  208.     return "Set the new attribute's name.";
  209.   }
  210.   /**
  211.    * Get the name of the attribute to be created
  212.    *
  213.    * @return the new attribute name
  214.    */
  215.   public String getAttributeName() {
  216.     return m_Name;
  217.   }
  218.   /** 
  219.    * Set the new attribute's name
  220.    *
  221.    * @param name the new name
  222.    */
  223.   public void setAttributeName(String name) {
  224.     String newName = name.trim();
  225.     if (newName.indexOf(' ') >= 0) {
  226.       if (newName.indexOf(''') != 0) {
  227. newName = newName.replace(''',' ');
  228.       }
  229.       newName = ''' + newName + ''';
  230.     }
  231.     if (newName.equals("")) {
  232.       newName = "unnamed";
  233.     }
  234.     m_Name = newName;
  235.     
  236.   }
  237.   /**
  238.    * Returns the tip text for this property
  239.    *
  240.    * @return tip text for this property suitable for
  241.    * displaying in the explorer/experimenter gui
  242.    */
  243.   public String attributeIndexTipText() {
  244.     return "The position (from 0) where the attribute will be inserted."
  245.       + " Use -1 to indicate the last attribute.";
  246.   }
  247.   /**
  248.    * Get the index where the attribute will be inserted
  249.    *
  250.    * @return the attribute insertion index
  251.    */
  252.   public int getAttributeIndex() {
  253.     return m_Insert;
  254.   }
  255.   /**
  256.    * Set the index where the attribute will be inserted
  257.    *
  258.    * @param attributeIndex the insertion index (-1 means last)
  259.    */
  260.   public void setAttributeIndex(int attributeIndex) {
  261.     m_Insert = attributeIndex;
  262.   }
  263.   /**
  264.    * Returns the tip text for this property
  265.    *
  266.    * @return tip text for this property suitable for
  267.    * displaying in the explorer/experimenter gui
  268.    */
  269.   public String nominalLabelsTipText() {
  270.     return "The list of value labels (nominal attribute creation only). "
  271.       + " The list must be comma-separated, eg: "red,green,blue"."
  272.       + " If this is empty, the created attribute will be numeric.";
  273.   }
  274.   /**
  275.    * Get the list of labels for nominal attribute creation
  276.    *
  277.    * @return the list of labels for nominal attribute creation
  278.    */
  279.   public String getNominalLabels() {
  280.     String labelList = "";
  281.     for(int i = 0; i < m_Labels.size(); i++) {
  282.       if (i == 0) {
  283. labelList = (String)m_Labels.elementAt(i);
  284.       } else {
  285. labelList += "," + (String)m_Labels.elementAt(i); 
  286.       }
  287.     }
  288.     return labelList;
  289.   }
  290.   /**
  291.    * Set the labels for nominal attribute creation.
  292.    *
  293.    * @param labelList a comma separated list of labels
  294.    * @exception IllegalArgumentException if the labelList was invalid
  295.    */
  296.   public void setNominalLabels(String labelList) {
  297.     FastVector labels = new FastVector (10);
  298.     // Split the labelList up into the vector
  299.     int commaLoc;
  300.     while ((commaLoc = labelList.indexOf(',')) >= 0) {
  301.       String label = labelList.substring(0, commaLoc).trim();
  302.       if (!label.equals("")) {
  303. labels.addElement(label);
  304.       } else {
  305. throw new IllegalArgumentException("Invalid label list at "+
  306.                                            labelList.substring(commaLoc));
  307.       }
  308.       labelList = labelList.substring(commaLoc + 1);
  309.     }
  310.     String label = labelList.trim();
  311.     if (!label.equals("")) {
  312.       labels.addElement(label);
  313.     }
  314.     // If everything is OK, make the type change
  315.     m_Labels = labels;
  316.     if (labels.size() == 0) {
  317.       m_AttributeType = Attribute.NUMERIC;
  318.     } else {
  319.       m_AttributeType = Attribute.NOMINAL; 
  320.     }
  321.   }
  322.   /**
  323.    * Main method for testing this class.
  324.    *
  325.    * @param argv should contain arguments to the filter: use -h for help
  326.    */
  327.   public static void main(String [] argv) {
  328.     try {
  329.       if (Utils.getFlag('b', argv)) {
  330.   Filter.batchFilterFile(new Add(), argv);
  331.       } else {
  332. Filter.filterFile(new Add(), argv);
  333.       }
  334.     } catch (Exception ex) {
  335.       System.out.println(ex.getMessage());
  336.     }
  337.   }
  338. }