2
$\begingroup$

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.

$\endgroup$
1
$\begingroup$

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.

Original answer:

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)$

$\endgroup$
  • $\begingroup$ I am using Mathematica 11 version SubsetMap is not working. Secondly @C.E. outcome is different as I want. $\endgroup$ – SAAN Jun 22 at 4:30
  • $\begingroup$ 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. $\endgroup$ – SAAN Jun 22 at 5:35
  • $\begingroup$ @SAAN, please see the updated version. $\endgroup$ – kglr Jun 22 at 7:10
  • $\begingroup$ It is working now. Thank you. $\endgroup$ – SAAN Jun 22 at 7:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.