@SuppressWarnings("unused")
	public String avgRow(int r, int[] columns)
	{
		//counters used to make sure that all items found across the
		//row are of the same type. To calculate an average, one of these
		//counters must be greater than one, while the rest should be zero.
		int Strings = 0;
		int integers = 0;
		int floats = 0;
		int doubles = 0;
		int datetimes = 0;

		ArrayList<String> row = new ArrayList<String>();

		//for the columns we want to average the rows over
		for (int i = 0; i < columns.length; i++)
		{
			//get the data type of the value ion the cell
			String type = RegexWrapper.getStringType(getCell(r, columns[i]));

			//if this is a value we can sum
			if (type.equals("int"))
			{
				integers++;
				row.add(getCell(r, columns[i]));
			}
			else if (type.equals("float"))
			{
				floats++;
				row.add(getCell(r, columns[i]));
			}
			else if (type.equals("double"))
			{
				doubles++;
				row.add(getCell(r, columns[i]));
			}
			else if (type.equals("date"))
			{
				datetimes++;
				row.add(getCell(r, columns[i]));
			}
			else if (type.equals("String"))
			{
				Strings++;
				return "";
			}
			else
			{
				return "NaN";
			}
		}

		//now check all row values are of the same type.
		if (integers == row.size())
		{
			int[] cells = Common.convertStringListToIntArray(row);
			return Cast.DoubleToString(StatsOps.Average(cells));
		}
		else if (floats == row.size())
		{
			float[] cells = Common.convertStringListToFloatArray(row);
			return Cast.FloatToString(StatsOps.Average(cells));
		}
		else if (doubles == row.size())
		{
			double[] cells = Common.convertStringListToDoubleArray(row);
			return Cast.DoubleToString(StatsOps.Average(cells));
		}
		else
			return "NaN";
	}