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