code: function newDataFrame(columns, colNames, validateCols) {
    var i;
    var nCol = columns.length;
  
    validateCols = isUndefined(validateCols) ? true : validateCols;
    if (validateCols) {
      var nRow = 1;
      for (i = 0; i < nCol; i++) {
        columns[i] = ensureVector(columns[i]);
        var colLen = columns[i].values.length;
        if (colLen !== 1) {
          if (nRow === 1) {
            nRow = colLen;
          } else if (colLen !== nRow) {
            throw new Error('incompatible column lengths found during ' +
              'data frame construction: ' + nRow + ', ' + colLen);
          }
        }
      }
      // Expand any length-1 vectors if necessary
      if (nRow !== 1) {
        for (i = 0; i < nCol; i++) {
          if (columns[i].values.length === 1) {
            var value = columns[i].values[0];
            var newArray = allocArray(nRow);
            for (var j = 0; j < nRow; j++) {
              newArray[j] = value;
            }
            columns[i] = newVector(newArray, columns[i].dtype);
          }
        }
      }
    }
  
    // Figure out allDtype
    var allDtype = null;
    if (nCol > 0) {
      allDtype = columns[0].dtype;
      for (i = 1; i < nCol; i++) {
        if (columns[i].dtype !== allDtype) {
          allDtype = null;
          break;
        }
      }
    }
  
    // Create data frame
    var df = Object.create(dfProto);
    df._cols = columns;
    df._names = colNames;
    df._index = null;
    df.allDtype = allDtype;
  
    return df;
  }
docs: Creates a new data frame with the given 'columns' array and 'colNames' string vector.  If "validateCols" is true (the default), every element in 'columns' is explicitly converted to a vector and consistency of resulting lengths is checked, expanding length-1 vectors if necessary. Otherwise, 'columns' is assumed to already contain vectors all of the same length