package water.rapids.ast.prims.mungers; import water.MRTask; import water.fvec.Chunk; import water.fvec.Frame; import water.fvec.NewChunk; import water.fvec.Vec; import water.rapids.Env; import water.rapids.ast.AstRoot; import water.rapids.vals.ValFrame; import water.rapids.ast.AstPrimitive; import java.util.Arrays; /** */ public class AstSetLevel extends AstPrimitive { @Override public String[] args() { return new String[]{"ary", "level"}; } @Override public int nargs() { return 1 + 2; } // (setLevel x level) @Override public String str() { return "setLevel"; } @Override public ValFrame apply(Env env, Env.StackHelp stk, AstRoot asts[]) { Frame fr = stk.track(asts[1].exec(env)).getFrame(); if (fr.numCols() != 1) throw new IllegalArgumentException("`setLevel` works on a single column at a time."); String[] doms = fr.anyVec().domain().clone(); if (doms == null) throw new IllegalArgumentException("Cannot set the level on a non-factor column!"); String lvl = asts[2].exec(env).getStr(); final int idx = Arrays.asList(doms).indexOf(lvl); if (idx == -1) throw new IllegalArgumentException("Did not find level `" + lvl + "` in the column."); // COW semantics Frame fr2 = new MRTask() { @Override public void map(Chunk c, NewChunk nc) { for (int i = 0; i < c._len; ++i) nc.addNum(idx); } }.doAll(new byte[]{Vec.T_NUM}, fr.anyVec()).outputFrame(null, fr.names(), fr.domains()); return new ValFrame(fr2); } }