//------------------------------------------//
// JSL Script for Blog Post Titled:
// Principal Components or Factor Analysis?
// Author: Laura Castro-Schilo
// April 20, 2017
//------------------------------------------//

//Simulate data
	RandomReset(1234);
	mymat = J(1000, 4, random normal());
	AsTable(mymat) << SetName("Simulated Random Normal Deviates");

//Map on correlations
	obj1 = Multivariate(
		Y( :Col1, :Col2, :Col3, :Col4 ),
		Estimation Method( "Row-wise" ),
		Scatterplot Matrix(0),
		Color Map on Correlations( 1 )
	);

	rpt1 = obj1 << Report();
	corr = rpt1[OutlineBox("Correlations")][MatrixBox(1)] << Get();

//Factor Analysis platform for PCA and EFA
	obj2 = Factor Analysis(
		   Y( :Col1, :Col2, :Col3, :Col4 ),
		   Variance Scaling( "Correlations" ),
		   Fit( "PC", "ONE", 1, "Unrotated",
				  Final Communality Estimates(0),
				  Variance Explained by Each Factor(0)
				  ),
		   Fit( "PC", "SMC", 1, "Unrotated",
				  Final Communality Estimates(0),
				  Variance Explained by Each Factor(0)
				  ),
		   SendToReport(
			Dispatch(
				{},
				"Factor Analysis on Correlations with 1 Factors: Principal Axis / Unrotated",
				OutlineBox,
				{Set Title( "Principal Components Analysis" )}
			),
			Dispatch(
				{},
				"Factor Analysis on Correlations with 1 Factors: Principal Axis / Unrotated",
				Outline Box( 2 ),
				{Set Title( "Exploratory Factor Analysis" )}
			)
		)
	);

//Create reduced correlation matrix
	rpt2 = obj2 << Report();
	smcs = rpt2[OutlineBox("Prior Communality Estimates:SMC")][MatrixBox(1)] << Get();

	reducedCorr = corr;
	reducedCorr[Loc(corr == 1)] = smcs;

//Create data table for color map on reduced correlation matrix
	forHeatMap = reducedCorr[0,1] |/ reducedCorr[0,2] |/ reducedCorr[0,3] |/ reducedCorr[0,4];
	yaxis = Repeat({"Col1"}, 4) || Repeat({"Col2"}, 4) || Repeat({"Col3"}, 4) || Repeat({"Col4"}, 4);
	xaxis = Repeat({"Col1", "Col2", "Col3", "Col4"}, 4);

	NewTable("Stacked",
		Add Rows(16),
		NewColumn("y", Character, Nominal, SetValues(yaxis)),
		NewColumn("x", Character, Nominal, SetValues(xaxis)),
		NewColumn("r", Numeric, Continuous, SetValues(forHeatMap))
	);
	
	DataTable("Stacked"):y << Set Property("Value Ordering", {"Col4", "Col3", "Col2", "Col1"} );

//Create color map on reduced correlation matrix
	DataTable("Stacked") <<
		Graph Builder(
			Size( 532, 448 ),
			Show Control Panel( 0 ),
			Variables( X( :x ), Y( :y ), Color( :r ) ),
			Elements( Heatmap( X, Y, Legend( 5 ) ) ),
			SendToReport(
				Dispatch(
					{},
					"400",
					ScaleBox,
					{Legend Model(
						5,
						Properties(
							0,
							{gradient(
								{Scale Values( [-1 0 1] ), Reverse Gradient( 1 ),
								Reverse Labels( 1 )}
							)}
						)
					)}
				),
				Dispatch(
					{},
					"graph title",
					TextEditBox,
					{Set Text( "Color Map on Reduced Correlation Matrix" )}
				),
				Dispatch( {}, "X title", TextEditBox, {Set Text( "" )} ),
				Dispatch( {}, "Y title", TextEditBox, {Set Text( "" )} )
			)
		);