function vi = makeVariableInfo(X,iscat,viName,terms)
%makeVariableInfo Make a VariableInfo table from a data table.

% The VariableInfo table contains one row for each variable. Columns give:
%    Class - class of the variable
%    Range - min/max for numeric variables, set of levels for categorical
%    InModel - true for a variable in the model as a predictor
%    IsCategorical - true for categorical variables

%   Copyright 2016-2023 The MathWorks, Inc.
if nargin<3
    viName = X.Properties.VariableNames;
end
nvars = length(viName);
if istable(X)
    viClass = varfun(@class,X,'OutputFormat','cell');
    viIsCategorical = varfun(@internal.stats.isDiscreteVar,X,'OutputFormat','uniform');
else
    viClass = repmat({class(X)},1,nvars);
    viIsCategorical = false(1,nvars);
end

% Based on the terms matrix, assign terms in/out of the model
% The terms matrix always has a last row to indicate including the response
% - remove that row, since InModel refers to predictors
viInModel = any(terms(1:end-1,:) > 0, 1)';

if ~isempty(iscat) && length(iscat)==nvars-1
    iscat(end+1) = false;
end

if ~isempty(iscat)
    viIsCategorical = internal.stats.bigdata.checkAsCat(viIsCategorical,iscat,nvars,true,viName);
end
viRange = cell(nvars,1);
for i = 1:nvars
    if istable(X)
        x = X.(viName{i});
    else
        x = X(:,i);
    end
    viRange{i} = internal.stats.bigdata.getVarRange(x,viIsCategorical(i),[]);
end
vi = table(viClass(:),viRange(:),viInModel(:),viIsCategorical(:), ...
    'VariableNames',{'Class' 'Range' 'InModel' 'IsCategorical'}, ...
    'RowNames',viName);
end