Coincidentally, I was just about to point out that, if you know you need linear regression and only want the parameters, then JSL is much faster. The code below took about 100 seconds on my laptop.
NamesDefaultToHere(1);
// Make some grouped data
gs = 10; // Group size
ng = 30000; // Number of groups
groupID = SortAscending(Repeat((1::ng)`, gs));
xVals = J(NRow(groupID), 1, RandomNormal());
yVals = J(NRow(groupID), 1, RandomNormal());
// Put the data in a table
dt1 = NewTable("Grouped Regression Data",
NewColumn("Group", Numeric, Nominal, Values(groupID)),
NewColumn("x", Numeric, Continuous, Values(xVals)),
NewColumn("y", Numeric, Continuous, Values(yVals)),
);
// Uncomment this block to use Fit Y By X to do the fitting
/*
// Use Fit Y By X
fxy = dt1 << Bivariate(Y( :y ), X( x ), Fit Line( {Line Color( {208, 64, 86} )} ), By(:Group));
// Get the pfitted parameters into a table
// (To do this interactively, right-click on any Parameter Estimates table in the report and select 'Make Combined Data Table')
fxyRep = fxy << Report;
dt2 = fxyRep[1][TableBox(3)] << makeCombinedDataTable;
// Split dt2
dt3 = dt2 << Split(Split By( :Term ), Split( :Estimate ), Group( :Group ), Remaining Columns( Drop All ));
dt3 << setName("Parameter Estimates from Fit Y By X");
Close(dt2, noSave);
*/
/// Do the linear regression in JSL, bypassing the platform . . .
// (1) Get the data from the table
xVals = Column(dt1, "x") << getAsMatrix;
yVals = Column(dt1, "y") << getAsMatrix;
groupID = Column(dt1, "Group") << getAsMatrix;
// (2) Add the unit vector to the design matrix
xVals = J(NRow(xVals), 1, 1)||xVals;
// (3) Do the linear regression for each group and store the results
beta = J(ng, 2, .);
for (g=1, g <= ng, g++,
thisGroup = Loc(groupID == g);
beta[g, 0] = Transpose(Inv(xVals[thisGroup, 0]`*xVals[thisGroup, 0])*xVals[thisGroup, 0]`*yVals[thisGroup]);
);
// (4) Make the table of results
dt4 = AsTable(beta);
dt4 << setName("Parameter Estimates from JSL");
Column(dt4, "Col1") << setName("Intercept");
Column(dt4, "Col2") << setName("x");