Используя tidyverse
и data.table
, вы можете сделать:
df %>%
rowid_to_column() %>%
group_by(x, rleid(x)) %>%
summarise(res = ifelse(min(rowid) != max(rowid),
paste(min(rowid), max(rowid), sep = ":"), paste(rowid))) %>%
group_by(x) %>%
summarise(res = paste(res, collapse = ", "))
x res
<fct> <chr>
1 AJ5ter2 5:6
2 al-1Tter2 12:15
3 AY9ter2 7, 19
4 CY-Yter2 16:18
5 LK2ter2 1:4, 8:9
6 YY49ter2 10:11
Или то же самое с просто tidyverse
:
df %>%
rowid_to_column() %>%
group_by(x, x_rleid = {x_rleid = rle(as.numeric(x)); rep(seq_along(x_rleid$lengths), x_rleid$lengths)}) %>%
summarise(res = ifelse(min(rowid) != max(rowid),
paste(min(rowid), max(rowid), sep = ":"), paste(rowid))) %>%
group_by(x) %>%
summarise(res = paste(res, collapse = ", "))
Оба кода, во-первых, добавить столбецс идентификатором строки.Во-вторых, они группируются по «х» и идентификатору группы длин серий «х».В-третьих, они оценивают, равен ли минимальный идентификатор строки максимальному идентификатору строки.Если нет, они объединяют значение минимального и максимального идентификатора строки, разделенных :
, в противном случае используется только одно значение идентификатора строки.Наконец, они группируются по «х» и объединяют различные элементы по ,
.
Или, если вам нужны все значения, а не только диапазоны:
df %>%
rowid_to_column() %>%
group_by(x, x_rleid = {x_rleid = rle(as.numeric(x)); rep(seq_along(x_rleid$lengths), x_rleid$lengths)}) %>%
summarise(res = paste(rowid, collapse = ",")) %>%
group_by(x) %>%
summarise(res = paste(res, collapse = ","))
x res
<fct> <chr>
1 AJ5ter2 5,6
2 al-1Tter2 12,13,14,15
3 AY9ter2 7,19
4 CY-Yter2 16,17,18
5 LK2ter2 1,2,3,4,8,9
6 YY49ter2 10,11