# How log-log analyses can make interactions appear from nowhere (Or mask them so that they are missed)!

## First, let's generate some random data...

rng(1); % Set the random number generator for consistency.

Mu = [93,107]; % Variable X1 will have a mean of 93, X2 will have a mean of 107.

Sigma = [50,-45;-45,50]; % Define the covariance matrix.

N = 1440; % Set the numbert of data points.

X = mvnrnd(Mu,Sigma,N); % Call the random number generator.

X1 = X(:,1); % Split the result in variable X1.

X2 = X(:,2); % Split the result in variable X2.

## Here we mean split the data (in a fancy way) to make 2 groups...

One group will be coloured red (the "Red" group), the other will be coloured blue (the "Blu" group). The fanciness involves a singular value decomposition. This ensures the split is vertical will respect to the regression line rather than being vertical with respect to either X1 or X2.

% Run a singular value decomposition to describe the data with 2 parameters rather than 4...

% ... That is, characterise the data as laying along a single line so that we can mean split

% points and colour them appropriately.

[U,S,V] = svd(X);

Selector = U(:,2) > mean(U(:,2)); % Select the points above the mean of the 2nd left singular value..

% N.B. As the data are not mean centred, the 1st singular value will reflect the mean.

Colours = [ones(N,1).*Selector,zeros(N,1),ones(N,1).*~Selector];

## Find the Betas describing the relationship between X1 and X2 for each group separately...

Betas_Red_PreLog = pinv([ones(sum(Selector),1),X1(Selector)]) * X2(Selector);

Betas_Blu_PreLog = pinv([ones(sum(~Selector),1),X1(~Selector)]) * X2(~Selector);

% Compute the normalised difference between slopes (Red-Blu)...

SlopeDiff_PreLog = Betas_Red_PreLog(2) - Betas_Blu_PreLog(2);

## Plot the data before applying the log-log transform...

figure;

scatter(X1,X2,50,Colours,'filled','MarkerEdgeColor','k');

title('Pre-Log');

hold on;

% Red:

line([min(X1(Selector));max(X1(Selector))],...

[1,min(X1(Selector));1,max(X1(Selector))]*Betas_Red_PreLog,...

'LineW',2,'Color',[1,0.5,0]);

% Blu:

line([min(X1(~Selector));max(X1(~Selector))],...

[1,min(X1(~Selector));1,max(X1(~Selector))]*Betas_Blu_PreLog,...

'LineW',2,'Color',[0,0.5,1]);

% Disply the difference in slopes:

text(85,130,sprintf('Red slope = %f%cBlu slope = %f;%cSlope difference = %f;',...

Betas_Red_PreLog(2),10,Betas_Blu_PreLog(2),10,SlopeDiff_PreLog));

## Now log transform the data...

lX1 = log(X1);

lX2 = log(X2);

% Find the betas again;

Betas_Red_PostLog = pinv([ones(sum(Selector),1),lX1(Selector)])*lX2(Selector);

Betas_Blu_PostLog = pinv([ones(sum(~Selector),1),lX1(~Selector)])*lX2(~Selector);

% Compute the normalised difference between slopes (Red-Blu)...

SlopeDiff_PostLog = Betas_Red_PostLog(2) - Betas_Blu_PostLog(2);

## Plot the data after applying the log-log transform...

figure;

scatter(lX1,lX2,50,Colours,'filled','MarkerEdgeColor','k');

title('Post-Log');

hold on;

% High:

line([min(lX1(Selector));max(lX1(Selector))],...

[1,min(lX1(Selector));1,max(lX1(Selector))]*Betas_Red_PostLog,...

'LineW',2,'Color',[1,0.5,0]);

% Low:

line([min(lX1(~Selector));max(lX1(~Selector))],...

[1,min(lX1(~Selector));1,max(lX1(~Selector))]*Betas_Blu_PostLog,...

'LineW',2,'Color',[0,0.5,1]);

text(4.25,4.4,sprintf('Red slope = %f%cBlu slope = %f;%cSlope difference = %f;',...

Betas_Red_PostLog(2),10,Betas_Blu_PostLog(2),10,SlopeDiff_PostLog));