private ValFrame colwise(Env env, Env.StackHelp stk, Frame fr, AstPrimitive fun) {
    // Break each column into it's own Frame, then execute the function passing
    // the 1 argument.  All columns are independent, and this loop should be
    // parallized over each column.
    Vec vecs[] = fr.vecs();
    Val vals[] = new Val[vecs.length];
    AstRoot[] asts = new AstRoot[]{fun, null};
    for (int i = 0; i < vecs.length; i++) {
      asts[1] = new AstFrame(new Frame(new String[]{fr._names[i]}, new Vec[]{vecs[i]}));
      try (Env.StackHelp stk_inner = env.stk()) {
        vals[i] = fun.apply(env, stk_inner, asts);
      }
    }

    // All the resulting Vals must be the same scalar type (and if ValFrames,
    // the columns must be the same count and type).  Build a Frame result with
    // 1 row column per applied function result (per column), and as many rows
    // as there are columns in the returned Frames.
    Val v0 = vals[0];
    Vec ovecs[] = new Vec[vecs.length];
    switch (v0.type()) {
      case Val.NUM:
        for (int i = 0; i < vecs.length; i++)
          ovecs[i] = Vec.makeCon(vals[i].getNum(), 1L); // Since the zero column is a number, all must be numbers
        break;
      case Val.FRM:
        long nrows = v0.getFrame().numRows();
        for (int i = 0; i < vecs.length; i++) {
          Frame res = vals[i].getFrame(); // Since the zero column is a frame, all must be frames
          if (res.numCols() != 1)
            throw new IllegalArgumentException("apply result Frames must have one column, found " + res.numCols() + " cols");
          if (res.numRows() != nrows)
            throw new IllegalArgumentException("apply result Frames must have all the same rows, found " + nrows + " rows and " + res.numRows());
          ovecs[i] = res.vec(0);
        }
        break;
      case Val.NUMS:
        for (int i = 0; i < vecs.length; i++)
          ovecs[i] = Vec.makeCon(vals[i].getNums()[0], 1L);
        break;
      case Val.STRS:
        throw H2O.unimpl();
      case Val.FUN:
        throw water.H2O.unimpl();
      case Val.STR:
        throw water.H2O.unimpl();
      default:
        throw water.H2O.unimpl();
    }
    return new ValFrame(new Frame(fr._names, ovecs));
  }
private ValFrame colwise ( Env env , Env . StackHelp stk , Frame fr , AstPrimitive fun ) { Vec vecs [ ] = fr . vecs ( ) ; Val vals [ ] = new Val [ vecs . length ] ; AstRoot [ ] asts = new AstRoot [ ] { fun , null } ; for ( int i = 0 ; i < vecs . length ; i ++ ) { asts [ 1 ] = new AstFrame ( new Frame ( new String [ ] { fr . _names [ i ] } , new Vec [ ] { vecs [ i ] } ) ) ; try ( Env . StackHelp stk_inner = env . stk ( ) ) { vals [ i ] = fun . apply ( env , stk_inner , asts ) ; } } Val v0 = vals [ 0 ] ; Vec ovecs [ ] = new Vec [ vecs . length ] ; switch ( v0 . type ( ) ) { case Val . NUM : for ( int i = 0 ; i < vecs . length ; i ++ ) ovecs [ i ] = Vec . makeCon ( vals [ i ] . getNum ( ) , 1L ) ; break ; case Val . FRM : long nrows = v0 . getFrame ( ) . numRows ( ) ; for ( int i = 0 ; i < vecs . length ; i ++ ) { Frame res = vals [ i ] . getFrame ( ) ; if ( res . numCols ( ) != 1 ) throw new IllegalArgumentException ( "apply result Frames must have one column, found " + res . numCols ( ) + " cols" ) ; if ( res . numRows ( ) != nrows ) throw new IllegalArgumentException ( "apply result Frames must have all the same rows, found " + nrows + " rows and " + res . numRows ( ) ) ; ovecs [ i ] = res . vec ( 0 ) ; } break ; case Val . NUMS : for ( int i = 0 ; i < vecs . length ; i ++ ) ovecs [ i ] = Vec . makeCon ( vals [ i ] . getNums ( ) [ 0 ] , 1L ) ; break ; case Val . STRS : throw H2O . unimpl ( ) ; case Val . FUN : throw water . H2O . unimpl ( ) ; case Val . STR : throw water . H2O . unimpl ( ) ; default : throw water . H2O . unimpl ( ) ; } return new ValFrame ( new Frame ( fr . _names , ovecs ) ) ; }
--------------------------------------------------------------------------