Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs	(revision 14349)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs	(revision 14350)
@@ -110,5 +110,21 @@
       } else {
         // no subtrees
-        if (node.Symbol is Variable) {
+        if (node.Symbol is LaggedVariable) {
+          var varNode = node as LaggedVariableTreeNode;
+          if (!varNode.Weight.IsAlmost(1.0)) {
+            strBuilder.Append("(");
+            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Weight);
+            strBuilder.Append("*");
+          }
+          strBuilder.Append("LAG(");
+          if (varNode.VariableName.Contains("'")) {
+            strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
+          } else {
+            strBuilder.AppendFormat("'{0}'", varNode.VariableName);
+          }
+          strBuilder.Append(", ")
+            .AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Lag)
+            .Append(")");
+        } else if (node.Symbol is Variable) {
           var varNode = node as VariableTreeNode;
           if (!varNode.Weight.IsAlmost(1.0)) {
@@ -130,5 +146,5 @@
             strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constNode.Value);
           else
-            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value);     // (-1)
+            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value); // (-1
         }
       }
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs	(revision 14349)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs	(revision 14350)
@@ -26,4 +26,5 @@
 using System.Text;
 using HeuristicLab.Collections;
+using HeuristicLab.Common;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 
@@ -109,4 +110,5 @@
         { "XOR", new Xor()},
         { "DIFF", new Derivative()},
+        { "LAG", new LaggedVariable() },
       };
 
@@ -333,5 +335,5 @@
     }
 
-    // Fact = '(' Expr ')' | funcId '(' ArgList ')' | varId | number
+    // Fact = '(' Expr ')' | 'LAG' '(' varId ',' ['+' | '-'] number ')' | funcId '(' ArgList ')' | varId | number
     private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) {
       var next = tokens.Peek();
@@ -353,11 +355,35 @@
           if (lPar.TokenType != TokenType.LeftPar)
             throw new ArgumentException("expected (");
-          var args = ParseArgList(tokens);
-
-          // check semantic constraints
-          if (funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length)
-            throw new ArgumentException(string.Format("Symbol {0} requires between {1} and  {2} arguments.", funcId,
-              funcNode.Symbol.MinimumArity, funcNode.Symbol.MaximumArity));
-          foreach (var arg in args) funcNode.AddSubtree(arg);
+
+          // handle 'lag' specifically
+          if (funcNode.Symbol is LaggedVariable) {
+            var varId = tokens.Dequeue();
+            if (varId.TokenType != TokenType.Identifier) throw new ArgumentException("Identifier expected. Format for lagged variables: \"lag(x, -1)\"");
+            var comma = tokens.Dequeue();
+            if (comma.TokenType != TokenType.Comma) throw new ArgumentException("',' expected, Format for lagged variables: \"lag(x, -1)\"");
+            double sign = 1.0;
+            if (tokens.Peek().strVal == "+" || tokens.Peek().strVal == "-") {
+              // read sign
+              var signTok = tokens.Dequeue();
+              if (signTok.strVal == "-") sign = -1.0;
+            }
+            var lagToken = tokens.Dequeue();
+            if (lagToken.TokenType != TokenType.Number) throw new ArgumentException("Number expected, Format for lagged variables: \"lag(x, -1)\"");
+            if (!lagToken.doubleVal.IsAlmost(Math.Round(lagToken.doubleVal)))
+              throw new ArgumentException("Time lags must be integer values");
+            var laggedVarNode = funcNode as LaggedVariableTreeNode;
+            laggedVarNode.VariableName = varId.strVal;
+            laggedVarNode.Lag = (int)Math.Round(sign * lagToken.doubleVal);
+            laggedVarNode.Weight = 1.0;
+          } else {
+            // functions
+            var args = ParseArgList(tokens);
+            // check number of arguments
+            if (funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length) {
+              throw new ArgumentException(string.Format("Symbol {0} requires between {1} and  {2} arguments.", funcId,
+                funcNode.Symbol.MinimumArity, funcNode.Symbol.MaximumArity));
+            }
+            foreach (var arg in args) funcNode.AddSubtree(arg);
+          }
 
           var rPar = tokens.Dequeue();
Index: /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/InfixExpressionParserTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/InfixExpressionParserTest.cs	(revision 14349)
+++ /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/InfixExpressionParserTest.cs	(revision 14350)
@@ -101,4 +101,9 @@
       Console.WriteLine(formatter.Format(parser.Parse("IF(LT(0,1), 1 , 0)")));
 
+      Console.WriteLine(formatter.Format(parser.Parse("LAG(x, 1)")));
+      Console.WriteLine(formatter.Format(parser.Parse("LAG(x, -1)")));
+      Console.WriteLine(formatter.Format(parser.Parse("LAG(x, +1)")));
+      Console.WriteLine(formatter.Format(parser.Parse("x * LAG('x', +1)")));
+
     }
   }
