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