#r
Вопрос:
Учитывая матрицу, подобную следующей:
p1 p2
[1,] 1 1065
[2,] 1 1465
[3,] 2 1464
[4,] 3 1463
[5,] 4 1462
[6,] 27 438
[7,] 29 635
[8,] 31 1012
[9,] 46 768
[10,] 53 1466
[11,] 63 401
[12,] 74 966
[13,] 75 1689
[14,] 86 682
[15,] 87 683
[16,] 90 612
[17,] 92 1608
Как я могу построить индекс, который идентифицирует парные запуски в p1 и p2? Могу ли я определить, что строки 2-5 представляют собой парные прогоны, а строки 14-15 представляют собой парные прогоны, в то время как 12-13, хотя и сопряжены в p1, не сопряжены в p2. Если этот вопрос можно было бы улучшить с помощью разъяснений, пожалуйста, дайте мне знать.
Примеры данных:
structure(c(1L, 1L, 2L, 3L, 4L, 27L, 29L, 31L, 46L, 53L, 63L,
74L, 75L, 86L, 87L, 90L, 92L, 1065L, 1465L, 1464L, 1463L, 1462L,
438L, 635L, 1012L, 768L, 1466L, 401L, 966L, 1689L, 682L, 683L,
612L, 1608L), .Dim = c(17L, 2L), .Dimnames = list(NULL, c("p1",
"p2")))
Ответ №1:
Что-то вроде этого?
m <- structure(c(1L, 1L, 2L, 3L, 4L, 27L, 29L, 31L, 46L, 53L, 63L,
74L, 75L, 86L, 87L, 90L, 92L, 1065L, 1465L, 1464L, 1463L, 1462L,
438L, 635L, 1012L, 768L, 1466L, 401L, 966L, 1689L, 682L, 683L,
612L, 1608L), .Dim = c(17L, 2L), .Dimnames = list(NULL, c("p1",
"p2")))
m <- m[order(m[,1], m[,2]),]
blnRun <- abs(diff(m[, "p1"])) == 1 amp; abs(diff(m[, "p2"])) == 1
cbind(m, idxRun = cumsum(c(blnRun, FALSE) amp; !c(FALSE, blnRun))*(c(FALSE, blnRun) | c(blnRun, FALSE)))
#> p1 p2 idxRun
#> [1,] 1 1065 0
#> [2,] 1 1465 1
#> [3,] 2 1464 1
#> [4,] 3 1463 1
#> [5,] 4 1462 1
#> [6,] 27 438 0
#> [7,] 29 635 0
#> [8,] 31 1012 0
#> [9,] 46 768 0
#> [10,] 53 1466 0
#> [11,] 63 401 0
#> [12,] 74 966 0
#> [13,] 75 1689 0
#> [14,] 86 682 2
#> [15,] 87 683 2
#> [16,] 90 612 0
#> [17,] 92 1608 0
Комментарии:
1. Это довольно близко к тому, о чем я думал. Если вы не можете гарантировать, что p2 всегда упорядочен — то есть, если первые два значения в p2 в данном случае были перевернуты — может ли это все еще работать?
2. Нет, это не так. Но это легко исправить: к тому времени упорядочьте матрицу
p1
p2
. Я обновил ответ.
Ответ №2:
Другое решение, основанное на dplyr
и data.table::rleid
:
library(tidyverse)
df <- structure(c(1L, 1L, 2L, 3L, 4L, 27L, 29L, 31L, 46L, 53L, 63L,
74L, 75L, 86L, 87L, 90L, 92L, 1065L, 1465L, 1464L, 1463L, 1462L,
438L, 635L, 1012L, 768L, 1466L, 401L, 966L, 1689L, 682L, 683L,
612L, 1608L), .Dim = c(17L, 2L), .Dimnames = list(NULL, c("p1",
"p2")))
df %>%
as.data.frame %>%
mutate(
idx1 = ifelse(abs(lag(p2)-p2) == 1 amp; abs(lag(p1)-p1) == 1,1,0),
idx2 = ifelse(abs(lead(p2)-p2) == 1 amp; abs(lead(p1)-p1) == 1,1,0),
idx = pmax(idx1,idx2, na.rm = T),
idx2 = idx,
idx = ifelse(idx != 0, data.table::rleid(idx), 0),
idx1 = NULL) %>%
group_by(idx2) %>%
mutate(idx = ifelse(idx == 0, 0, data.table::rleid(idx))) %>%
ungroup %>% select(-idx2)
#> # A tibble: 17 × 3
#> p1 p2 idx
#> <int> <int> <dbl>
#> 1 1 1065 0
#> 2 1 1465 1
#> 3 2 1464 1
#> 4 3 1463 1
#> 5 4 1462 1
#> 6 27 438 0
#> 7 29 635 0
#> 8 31 1012 0
#> 9 46 768 0
#> 10 53 1466 0
#> 11 63 401 0
#> 12 74 966 0
#> 13 75 1689 0
#> 14 86 682 2
#> 15 87 683 2
#> 16 90 612 0
#> 17 92 1608 0