# Bivariate Array Arrangements

I want to

1. Generate a bivariate data set (X,Y) of m*m
2. Arrange each row with respect to X
3. Note the order of Y associated with X
4. From the first row, pick the first element order of X, along with Y and their orders as well (Y order is random from 1,2,..m). From second row 2nd order with respect to X, along with Y and their orders...similarly from mth row m order with respect to X, along with Y and their orders.

I have done this with the following code:

 m = 3;
dist = BinormalDistribution[{1, 2}, {0.5, 0.5}, 0.5];
data1 = RandomVariate[dist, {m, m}];

data2 = Table[Sort[data1[[i]], #1[[1]] < #2[[1]] &], {i, 1, m}]
data20 = Table[Table[data2[[j, i, 1]], {i, 1, m}], {j, 1, m}];
data21 = Table[Table[data2[[j, i, 2]], {i, 1, m}], {j, 1, m}];

data210 = Table[Table[RankedMin[data21[[j]], i], {i, 1, m}], {j, 1, m}]
data4 = {1, 2, 3};

data24 = Table[
Table[{data20[[j, i]], data4[[i]]}, {i, 1, m}], {j, 1, m}]
data212 =
Table[Table[{data210[[j, i]], data4[[i]]}, {i, 1, m}], {j, 1, m}]
data51 = Table[
Table[If[{data2[[1, 1, 2]]} == {data212[[j, i, 1]]},
data212[[j, i]], {}], {i, 1, m}], {j, 1, 3}] //. {} :>
Unevaluated[## &[]];
data52 = Table[
Table[If[{data2[[2, 2, 2]]} == {data212[[j, i, 1]]},
data212[[j, i]], {}], {i, 1, m}], {j, 1, 3}] //. {} :>
Unevaluated[## &[]];
data53 = Table[
Table[If[{data2[[3, 3, 2]]} == {data212[[j, i, 1]]},
data212[[j, i]], {}], {i, 1, m}], {j, 1, 3}] //. {} :>
Unevaluated[## &[]];

data61 = {{data24[[1, 1]], data51 // Flatten}, {data24[[2, 2]],
data52 // Flatten}, {data24[[3, 3]], data53 // Flatten}}


Although it is working but this is huge and quite boring, I need suggestions/solution for quick and short code. As this is only one step have to do alot with that.

Update: A collection of simple operators that can be pieced together to get concomitant values and ranks for columns of an input matrix:

ClearAll[ ranksF, sortBy, valuesAndRanksBy, concomitantsOf, diagonalConcomitantsOf]
ranksF = Transpose @* Map[Ordering @* Ordering] @* Transpose;
sortBy[col_] := #[[Ordering @ #[[All, col]]]] &
valuesAndRanksBy[col_] := {#, ranksF @ #} & @* sortBy[col]
concomitantsOf[col_] := Transpose[#, {3, 1, 2}] & @* valuesAndRanksBy[col]
diagonalConcomitantsOf[col_] := Diagonal @* Map[ concomitantsOf[col]]


Examples:

OP's request:

diagonalConcomitantsOf[1] @ data


{{{0.752703, 1}, {2.28054, 2}},
{{1.37034, 2}, {2.58315, 3}},
{{2.24332, 3}, {1.96183, 2}}}

Do the same for the second column:

diagonalConcomitantsOf[2] @ data


{{{0.924581, 2}, {2.21296, 1}},
{{1.95246, 3}, {2.27405, 2}},
{{1.17523, 1}, {2.46165, 3}}}

Get the column ranks of pairs for each row:

ranksF /@ data


{{{1, 2}, {2, 1}, {3, 3}},
{{3, 2}, {2, 3}, {1, 1}},
{{1, 3}, {2, 1}, {3, 2}}}

etc.

ClearAll[f1]

ranking = Ordering @* Ordering;
f1 = Diagonal[Transpose @*
Map[Transpose[{#, ranking @ #}] &] /@
Map[Transpose@*SortBy[ First] ] @ #] &;


Using specific matrix provided in the comments, f1 seems to give the desired result:

data = {{{0.752703, 2.28054}, {0.924581, 2.21296}, {1.12501, 2.6282}},
{{1.95246, 2.27405}, {1.37034, 2.58315}, {1.3276, 1.72714}},
{{1.17523, 2.46165}, {1.35104, 1.80316}, {2.24332, 1.96183}}};

f1 @ data


{{{0.752703, 1}, {2.28054, 2}},
{{1.37034, 2}, {2.58315, 3}},
{{2.24332, 3}, {1.96183, 2}}}

TeXForm @ MatrixForm[data, TableDirections -> Row]


$$\left( \begin{array}{ccc} \left( \begin{array}{cc} 0.752703 & 2.28054 \\ \end{array} \right) & \left( \begin{array}{cc} 1.95246 & 2.27405 \\ \end{array} \right) & \left( \begin{array}{cc} 1.17523 & 2.46165 \\ \end{array} \right) \\ \left( \begin{array}{cc} 0.924581 & 2.21296 \\ \end{array} \right) & \left( \begin{array}{cc} 1.37034 & 2.58315 \\ \end{array} \right) & \left( \begin{array}{cc} 1.35104 & 1.80316 \\ \end{array} \right) \\ \left( \begin{array}{cc} 1.12501 & 2.6282 \\ \end{array} \right) & \left( \begin{array}{cc} 1.3276 & 1.72714 \\ \end{array} \right) & \left( \begin{array}{cc} 2.24332 & 1.96183 \\ \end{array} \right) \\ \end{array} \right)$$

• I am using Mathematica 11 version SubsetMap is not working. Secondly @C.E. outcome is different as I want.
– SAAN
Jun 22 '19 at 4:30
• I have run your code and output is: {{{0.752703, 2.28054}, {0.924581, 2.21296}, {1.12501, 2.6282}}, {{1.95246, 2.27405}, {1.37034, 2.58315}, {1.3276, 1.72714}}, {{1.17523, 2.46165}, {1.35104, 1.80316}, {2.24332, 1.96183}}} this is 3*3 data set. And the selected outcome: {{{0.752703, 1}, {2.28054, 3}}, {{1.37034, 2}, {2.58315, 1}}, {{2.24332, 3}, {1.96183, 2}}}, 2.58315 order is 3 in second row. but in output it is 1.
– SAAN
Jun 22 '19 at 5:35
• @SAAN, please see the updated version.
– kglr
Jun 22 '19 at 7:10
• It is working now. Thank you.
– SAAN
Jun 22 '19 at 7:43