private void writeMetadata(HashMap<String,Long> map,String outputDir,int colID,FileSystem fs,TfUtils agents,boolean fromCP) throws IOException {
  MVImputeAgent mvagent=agents.getMVImputeAgent();
  String mode=null;
  Long count=null;
  int rcdIndex=0, modeIndex=0;
  long maxCount=Long.MIN_VALUE;
  boolean isRecoded=(isApplicable(colID) != -1);
  boolean isModeImputed=(mvagent.getMethod(colID) == MVMethod.GLOBAL_MODE);
  Path pt=new Path(outputDir + "/Recode/" + agents.getName(colID)+ TfUtils.TXMTD_RCD_MAP_SUFFIX);
  BufferedWriter br=null;
  if (isRecoded)   br=new BufferedWriter(new OutputStreamWriter(fs.create(pt,true)));
  if (agents.getNAStrings() != null)   for (  String naword : agents.getNAStrings())   map.remove(naword);
  if (fromCP)   map=handleMVConstant(colID,agents,map);
  if (map.size() == 0)   throw new RuntimeException("Can not proceed since \"" + agents.getName(colID) + "\" (id="+ colID+ ") contains only the missing values, and not a single valid value -- set imputation method to \"constant\".");
  List<String> newNames=new ArrayList<String>(map.keySet());
  Collections.sort(newNames);
  for (  String w : newNames) {
    count=map.get(w);
    ++rcdIndex;
    if (br != null)     br.write(UtilFunctions.quote(w) + TfUtils.TXMTD_SEP + rcdIndex+ TfUtils.TXMTD_SEP+ count+ "\n");
    if (maxCount < count) {
      maxCount=count;
      mode=w;
      modeIndex=rcdIndex;
    }
    map.put(w,(long)rcdIndex);
  }
  if (br != null)   br.close();
  if (mode == null) {
    mode="";
    maxCount=0;
  }
  if (isRecoded) {
    pt=new Path(outputDir + "/Recode/" + agents.getName(colID)+ TfUtils.MODE_FILE_SUFFIX);
    br=new BufferedWriter(new OutputStreamWriter(fs.create(pt,true)));
    br.write(UtilFunctions.quote(mode) + "," + modeIndex+ ","+ maxCount);
    br.close();
    pt=new Path(outputDir + "/Recode/" + agents.getName(colID)+ TfUtils.TXMTD_RCD_DISTINCT_SUFFIX);
    br=new BufferedWriter(new OutputStreamWriter(fs.create(pt,true)));
    br.write("" + map.size());
    br.close();
  }
  if (isModeImputed) {
    pt=new Path(outputDir + "/Impute/" + agents.getName(colID)+ TfUtils.TXMTD_MV_FILE_SUFFIX);
    br=new BufferedWriter(new OutputStreamWriter(fs.create(pt,true)));
    br.write(colID + "," + UtilFunctions.quote(mode));
    br.close();
  }
}

private void writeMetadata ( HashMap < String , Long > map , String outputDir , int colID , FileSystem fs , TfUtils agents , boolean fromCP ) throws IOException { MVImputeAgent mvagent = agents . getMVImputeAgent ( ) ; String mode = null ; Long count = null ; int rcdIndex = 0 , modeIndex = 0 ; long maxCount = Long . MIN_VALUE ; boolean isRecoded = ( isApplicable ( colID ) != - 1 ) ; boolean isModeImputed = ( mvagent . getMethod ( colID ) == MVMethod . GLOBAL_MODE ) ; Path pt = new Path ( outputDir + "/Recode/" + agents . getName ( colID ) + TfUtils . TXMTD_RCD_MAP_SUFFIX ) ; BufferedWriter br = null ; if ( isRecoded ) br = new BufferedWriter ( new OutputStreamWriter ( fs . create ( pt , true ) ) ) ; if ( agents . getNAStrings ( ) != null ) for ( String naword : agents . getNAStrings ( ) ) map . remove ( naword ) ; if ( fromCP ) map = handleMVConstant ( colID , agents , map ) ; if ( map . size ( ) == 0 ) throw new RuntimeException ( "Can not proceed since \"" + agents . getName ( colID ) + "\" (id=" + colID + ") contains only the missing values, and not a single valid value -- set imputation method to \"constant\"." ) ; List < String > newNames = new ArrayList < String > ( map . keySet ( ) ) ; Collections . sort ( newNames ) ; for ( String w : newNames ) { count = map . get ( w ) ; ++ rcdIndex ; if ( br != null ) br . write ( UtilFunctions . quote ( w ) + TfUtils . TXMTD_SEP + rcdIndex + TfUtils . TXMTD_SEP + count + "\n" ) ; if ( maxCount < count ) { maxCount = count ; mode = w ; modeIndex = rcdIndex ; } map . put ( w , ( long ) rcdIndex ) ; } if ( br != null ) br . close ( ) ; if ( mode == null ) { mode = "" ; maxCount = 0 ; } if ( isRecoded ) { pt = new Path ( outputDir + "/Recode/" + agents . getName ( colID ) + TfUtils . MODE_FILE_SUFFIX ) ; br = new BufferedWriter ( new OutputStreamWriter ( fs . create ( pt , true ) ) ) ; br . write ( UtilFunctions . quote ( mode ) + "," + modeIndex + "," + maxCount ) ; br . close ( ) ; pt = new Path ( outputDir + "/Recode/" + agents . getName ( colID ) + TfUtils . TXMTD_RCD_DISTINCT_SUFFIX ) ; br = new BufferedWriter ( new OutputStreamWriter ( fs . create ( pt , true ) ) ) ; br . write ( "" + map . size ( ) ) ; br . close ( ) ; } if ( isModeImputed ) { pt = new Path ( outputDir + "/Impute/" + agents . getName ( colID ) + TfUtils . TXMTD_MV_FILE_SUFFIX ) ; br = new BufferedWriter ( new OutputStreamWriter ( fs . create ( pt , true ) ) ) ; br . write ( colID + "," + UtilFunctions . quote ( mode ) ) ; br . close ( ) ; } }
function to output transformation metadata , including : - recode maps , - number of distinct values , - mode , and - imputation value ( in the case of global_mode ) the column for which this function is invoked can be one of the following : - just recoded ( write . map , . ndistinct , . mode ) - just mv imputed ( w / global_mode ) ( write . impute ) - both recoded and mv imputed ( write . map , . ndistinct , . mode , . impute )
