| 16 | public final boolean useIntercept; |
| 17 | |
| 18 | public Formula(final String f) throws ParseException { |
| 19 | this.f = f; |
| 20 | final String[] sides = f.split("~"); |
| 21 | if(sides.length!=2) { |
| 22 | throw new ParseException("not a well formed formula (needs exactly one ~): '" + f + "'", 0); |
| 23 | } |
| 24 | resultColumn = sides[0].trim(); |
| 25 | final String[] terms = sides[1].split("\\+"); |
| 26 | boolean willUseIntercept = true; |
| 27 | for(final String termi: terms) { |
| 28 | final String ti = termi.trim(); |
| 29 | if(ti.length()<=0) { |
| 30 | throw new ParseException("not a well-formed expression (doubled plus) '" + f + "'", 0); |
| 31 | } |
| 32 | final char c0 = ti.charAt(0); |
| 33 | final boolean hasHash = c0=='#'; |
| 34 | final boolean hasCarat = c0=='^'; |
| 35 | if(ti.equals("0")) { |
| 36 | willUseIntercept = false; |
| 37 | } else if(hasHash) { |
| 38 | final String name = ti.substring(1).trim(); |
| 39 | if(name.length()<=0) { |
| 40 | throw new ParseException("not a well formed formula (empty name): '" + f + "'", 0); |
| 41 | } |
| 42 | forcedNumeric.add(name); |
| 43 | } if(hasCarat) { |
| 44 | final String name = ti.substring(1).trim(); |
| 45 | if(name.length()<=0) { |
| 46 | throw new ParseException("not a well formed formula (empty name): '" + f + "'", 0); |
| 47 | } |
| 48 | forcedCategorical.add(name); |
| 49 | } else { |
| 50 | final String name = ti.trim(); |
| 51 | if(name.length()>0) { |
| 52 | variables.add(name); |
| 53 | } |
| 54 | } |
| 55 | } |
| 56 | useIntercept = willUseIntercept; |
| 57 | variables.addAll(forcedCategorical); |
| 58 | variables.addAll(forcedNumeric); |
| 59 | } |
| 60 | |
| 61 | /** |
| 62 | * skip parsing version of the formula, user code alters the variable sets after construction |