package water.rapids.ast.prims.mungers;
import water.H2O;
import water.MRTask;
import water.fvec.Chunk;
import water.fvec.Frame;
import water.fvec.NewChunk;
import water.fvec.Vec;
import water.rapids.Val;
import water.rapids.ast.AstBuiltin;
import water.rapids.vals.ValFrame;
import water.rapids.vals.ValNum;
/**
* Split out in it's own function, instead of Yet Another UniOp, because it
* needs a "is.NA" check instead of just using the Double.isNaN hack... because
* it works on UUID and String columns.
*/
public class AstIsNa extends AstBuiltin<AstIsNa> {
@Override
public String[] args() {
return new String[]{"ary"};
}
@Override
public String str() {
return "is.na";
}
@Override
public int nargs() {
return 1 + 1;
}
@Override
public Val exec(Val... args) {
Val val = args[1];
switch (val.type()) {
case Val.NUM:
return new ValNum(op(val.getNum()));
case Val.FRM:
Frame fr = val.getFrame();
String[] newNames = new String[fr.numCols()];
for (int i = 0; i < newNames.length; i++) {
newNames[i] = "isNA(" + fr.name(i) + ")";
}
return new ValFrame(new MRTask() {
@Override
public void map(Chunk cs[], NewChunk ncs[]) {
for (int col = 0; col < cs.length; col++) {
Chunk c = cs[col];
NewChunk nc = ncs[col];
for (int i = 0; i < c._len; i++)
nc.addNum(c.isNA(i) ? 1 : 0);
}
}
}.doAll(fr.numCols(), Vec.T_NUM, fr).outputFrame(newNames, null));
case Val.STR:
return new ValNum(val.getStr() == null ? 1 : 0);
default:
throw H2O.unimpl("is.na unimpl: " + val.getClass());
}
}
double op(double d) {
return Double.isNaN(d) ? 1 : 0;
}
}