Home > OS >  How to use R's loop to get the part of the aggregate matrix other than the many subset matrices
How to use R's loop to get the part of the aggregate matrix other than the many subset matrices

Time:06-02

I have two matrices of pure numbers, and their format is the same: the first column is the group name, the second is the starting number, and the third is the ending number.

E.g (*spaces in the following tables represent column change): A row of table1:

scahrs1_999 1 12 #Means the total set of numbers for the 'scahrs1_999' group is 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14.

Some rows of table2:

scahrs1_999 2 3 scahrs1_999 6 8 scahrs1_999 11 12 #Means that the subsets of numbers in the 'scahrs1_999' group are '2, 3', '5, 6, 7', and '10, 11'.

The result I want to get is a set of numbers that do not contain any subsets in the total set, and behaves the same as a subset of table2's consecutive numbers. which is:

table3 (results):

scahrs1_999 1 scahrs1_999 4 5 scahrs1_999 9 10 scahrs1_999 13 14

Also exclude subsets with only 1 number. which is:

table3 (final result):

scahrs1_999 4 5 scahrs1_999 9 10 scahrs1_999 13 14

As shown below, I have thousands of groups similar to the above 'scahrs1_999'. Obviously, I can't calculate them one by one. I know that R can loop through each group with a 'loop program' and get the corresponding result. But my programming ability is not up to this complex job.

> head(Table1, 10)

      scahrs1_1 X1  X1870329
1    scahrs1_10  1    925472
2   scahrs1_100  1 187969291
3  scahrs1_1000  1     99113
4  scahrs1_1001  1     81142
5  scahrs1_1002  1     62661
6  scahrs1_1003  1    104891
7  scahrs1_1004  1     99296
8  scahrs1_1005  1     30919
9  scahrs1_1006  1     97599
10 scahrs1_1008  1     97078

> head(Table2, 100)

     scahrs1_1   X8158   X9159
1    scahrs1_1   17916   18917
2    scahrs1_1   18644   19645
3    scahrs1_1   31439   32440
4    scahrs1_1   37022   38023
5    scahrs1_1   62954   63955
6    scahrs1_1  123548  124549
7    scahrs1_1  129802  130803
8    scahrs1_1  135683  136684
9    scahrs1_1  135942  136943
10   scahrs1_1  172435  173436
11   scahrs1_1  198754  199755
12   scahrs1_1  215332  216333
13   scahrs1_1  222282  223283
14   scahrs1_1  246482  247483
15   scahrs1_1  257608  258609
16   scahrs1_1  265448  266449
17   scahrs1_1  279055  280056
18   scahrs1_1  281662  282663
19   scahrs1_1  284739  285740
20   scahrs1_1  300642  301643
21   scahrs1_1  302012  303013
22   scahrs1_1  373404  374405
23   scahrs1_1  403905  404906
24   scahrs1_1  411063  412064
25   scahrs1_1  422121  423122
26   scahrs1_1  431010  432011
27   scahrs1_1  435139  436140
28   scahrs1_1  446361  447362
29   scahrs1_1  456286  457287
30   scahrs1_1  471939  472940
31   scahrs1_1  483199  484200
32   scahrs1_1  490814  491815
33   scahrs1_1  509391  510392
34   scahrs1_1  513544  514545
35   scahrs1_1  531809  532810
36   scahrs1_1  539336  540337
37   scahrs1_1  566063  567064
38   scahrs1_1  589567  590568
39   scahrs1_1  605514  606515
40   scahrs1_1  611023  612024
41   scahrs1_1  619177  620178
42   scahrs1_1  637320  638321
43   scahrs1_1  646826  647827
44   scahrs1_1  651502  652503
45   scahrs1_1  659330  660331
46   scahrs1_1  661130  662131
47   scahrs1_1  675601  676602
48   scahrs1_1  705521  706522
49   scahrs1_1  707284  708285
50   scahrs1_1  754859  755860
51   scahrs1_1  755517  756518
52   scahrs1_1  759847  760848
53   scahrs1_1  784129  785130
54   scahrs1_1  791558  792559
55   scahrs1_1  809536  810537
56   scahrs1_1  833786  834787
57   scahrs1_1  856736  857737
58   scahrs1_1  967041  968042
59   scahrs1_1  972438  973439
60   scahrs1_1  984426  985427
61   scahrs1_1 1006376 1007377
62   scahrs1_1 1038948 1039949
63   scahrs1_1 1055150 1056151
64   scahrs1_1 1065899 1066900
65   scahrs1_1 1069468 1070469
66   scahrs1_1 1084511 1085512
67   scahrs1_1 1094554 1095555
68   scahrs1_1 1117600 1118601
69   scahrs1_1 1124012 1125013
70   scahrs1_1 1137890 1138891
71   scahrs1_1 1185043 1186044
72   scahrs1_1 1236571 1237572
73   scahrs1_1 1268598 1269599
74   scahrs1_1 1312486 1313487
75   scahrs1_1 1439214 1440215
76   scahrs1_1 1449118 1450119
77   scahrs1_1 1472136 1473137
78   scahrs1_1 1475392 1476393
79   scahrs1_1 1493690 1494691
80   scahrs1_1 1514717 1515718
81   scahrs1_1 1544335 1545336
82   scahrs1_1 1546822 1547823
83   scahrs1_1 1588222 1589223
84   scahrs1_1 1626292 1627293
85   scahrs1_1 1630551 1631552
86   scahrs1_1 1637472 1638473
87   scahrs1_1 1651989 1652990
88   scahrs1_1 1665592 1666593
89   scahrs1_1 1676511 1677512
90   scahrs1_1 1689150 1690151
91   scahrs1_1 1692526 1693527
92   scahrs1_1 1717730 1718731
93   scahrs1_1 1760841 1761842
94   scahrs1_1 1783827 1784828
95   scahrs1_1 1792539 1793540
96   scahrs1_1 1802578 1803579
97   scahrs1_1 1808581 1809582
98   scahrs1_1 1851128 1852129
99  scahrs1_10   22999   24000
100 scahrs1_10   39260   40261
> dput(head(Table1, 10))

structure(list(scahrs1_1 = c("scahrs1_10", "scahrs1_100", "scahrs1_1000",
"scahrs1_1001", "scahrs1_1002", "scahrs1_1003", "scahrs1_1004",
"scahrs1_1005", "scahrs1_1006", "scahrs1_1008"), X1 = c(1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), X1870329 = c(925472L, 187969291L,
99113L, 81142L, 62661L, 104891L, 99296L, 30919L, 97599L, 97078L
)), row.names = c(NA, 10L), class = "data.frame")

> dput(head(Table2, 10))

structure(list(scahrs1_1 = c("scahrs1_1", "scahrs1_1", "scahrs1_1",
"scahrs1_1", "scahrs1_1", "scahrs1_1", "scahrs1_1", "scahrs1_1",
"scahrs1_1", "scahrs1_1"), X8158 = c(17916L, 18644L, 31439L,
37022L, 62954L, 123548L, 129802L, 135683L, 135942L, 172435L),
    X9159 = c(18917L, 19645L, 32440L, 38023L, 63955L, 124549L,
    130803L, 136684L, 136943L, 173436L)), row.names = c(NA, 10L
), class = "data.frame")

Could someone give me some advice?

CodePudding user response:

It looks like some of the data is jumbled, but I believe this data.table solution will return the desired Table3 (modifying the posted dataset slightly to correct the mistakes):

library(data.table)

Table1 <- data.table(group = c("scahrs1_1", "scahrs1_10", "scahrs1_100", "scahrs1_1000", "scahrs1_1001", "scahrs1_1002", "scahrs1_1003", "scahrs1_1004", "scahrs1_1005", "scahrs1_1006", "scahrs1_1008"), idxStart = 1L, idXEnd = c(1870329L, 925472L, 187969291L, 99113L, 81142L, 62661L, 104891L, 99296L, 30919L, 97599L, 97078L))
Table2 <- data.table(group = c(rep("scahrs1_1", 11), rep("scahrs1_10", 2)), idxStart = c(8158L, 17916L, 18644L, 31439L, 37022L, 62954L, 123548L, 129802L, 135683L, 135942L, 172435L, 22999L, 39260L), idxEnd = c(9159L, 18917L, 19645L, 32440L, 38023L, 63955L, 124549L, 130803L, 136684L, 136943L, 173436L, 24000L, 40261L))

fBetween <- function(grp, idxStart, idxEnd) {
  idxRange <- unlist(Table1[group == grp, 2:3])
  if (idxStart[1] == idxRange[1]) {
    if (last(idxEnd) == idxRange[2]) {
      list(idxStart = first(idxEnd, -1)   1, idxEnd = last(idxStart, -1) - 1)
    } else {
      list(idxStart = idxEnd   1, idxEnd = c(last(idxStart, -1) - 1, idxRange[2]))
    }
  } else {
    if (last(idxEnd) == idxRange[2]) {
      list(idxStart = c(idxRange[1], first(idxEnd, -1)   1), idxEnd = idxStart - 1)
    } else {
      list(idxStart = c(idxRange[1], idxEnd   1), idxEnd = c(idxStart - 1, idxRange[2]))
    }
  }
}

Table3 <- setorder(Table2, group, idxStart)[, fBetween(first(group), idxStart, idxEnd), group][idxStart != idxEnd]
Table3
#>          group idxStart  idxEnd
#>  1:  scahrs1_1        1    8157
#>  2:  scahrs1_1     9160   17915
#>  3:  scahrs1_1    18918   18643
#>  4:  scahrs1_1    19646   31438
#>  5:  scahrs1_1    32441   37021
#>  6:  scahrs1_1    38024   62953
#>  7:  scahrs1_1    63956  123547
#>  8:  scahrs1_1   124550  129801
#>  9:  scahrs1_1   130804  135682
#> 10:  scahrs1_1   136685  135941
#> 11:  scahrs1_1   136944  172434
#> 12:  scahrs1_1   173437 1870329
#> 13: scahrs1_10        1   22998
#> 14: scahrs1_10    24001   39259
#> 15: scahrs1_10    40262  925472

CodePudding user response:

This function can be applied after grouping the two data.tables

f <- function(s,e,is,ie) {
  res = t(rbindlist(list(c(
      list(c(s[1],is[1]-1)),
      lapply(2:length(is), \(i) c(ie[i-1] 1, is[i]-1)),
      list(c(ie[length(ie)] 1, e[length(e)]))
  ))))
  list(start = res[,1], end = res[,2])
}

Usage (Using Table1 and Table2, courtesy of @jblood94)

Table1[Table2, on="group"][, f(idxStart, idxEnd, i.idxStart,i.idxEnd), by=group][start<end]

Output:

         group  start     end
 1:  scahrs1_1      1    8157
 2:  scahrs1_1   9160   17915
 3:  scahrs1_1  19646   31438
 4:  scahrs1_1  32441   37021
 5:  scahrs1_1  38024   62953
 6:  scahrs1_1  63956  123547
 7:  scahrs1_1 124550  129801
 8:  scahrs1_1 130804  135682
 9:  scahrs1_1 136944  172434
10:  scahrs1_1 173437 1870329
11: scahrs1_10      1   22998
12: scahrs1_10  24001   39259
13: scahrs1_10  40262  925472
  • Related