Есть ли простой способ разделить вектор повторяющихся значений в R на куски значений и получить индексы?

У меня есть фрейм данных данных разреза, так что для каждого разреза есть коды видов, и для каждого вида есть связанный счет. Я пытаюсь рассчитать долю разрезов, которые идентифицируют конкретный вид, разделив фрейм данных на каждый разрез. Как я могу взять вектор повторяющихся фрагментов чисел, разделить его на фрагменты с одинаковыми значениями и получить индексы?

Пример:

x <- c(1, 2, 1, 2, 3, 1)
y <- c(3, 2, 3, 3, 2, 3)
Transects <- rep(x, y)

Я хочу, чтобы он выводил такие куски

c(1, 1, 1)
c(2, 2)
c(1, 1, 1)
c(2, 2, 2)
c(3, 3)
c(1, 1, 1)

или, что более важно, связанные индексы, которые дали бы мне

c(1, 2, 3)
c(4, 5)
c(6, 7, 8)
c(9, 10, 11)
c(12, 13)
c(14, 15, 16) 

Я даже не знаю, какие функции попробовать, потому что я не знаю, по каким индексам разделить вектор, и не могу разделить по простому значению, потому что есть куски одинаковых значений, и я не хочу, чтобы они смешивались вместе, так как это разные разрезы. Любая помощь приветствуется, я даже не знаю, как создать функцию, которая могла бы это сделать.


person Vic    schedule 02.07.2020    source источник
comment
rleid от data.table пригодится: split(Transects, data.table::rleid(Transects)). Может быть полезно: stackoverflow.com/questions/33507868/   -  person markus    schedule 02.07.2020


Ответы (2)


Ты можешь сделать:

split(Transects, with(rle(Transects), rep(seq_along(values), lengths)))

$`1`
[1] 1 1 1

$`2`
[1] 2 2

$`3`
[1] 1 1 1

$`4`
[1] 2 2 2

$`5`
[1] 3 3

$`6`
[1] 1 1 1

Или, если вас интересуют индексы:

split(seq_along(Transects), with(rle(Transects), rep(seq_along(values), lengths)))

$`1`
[1] 1 2 3

$`2`
[1] 4 5

$`3`
[1] 6 7 8

$`4`
[1]  9 10 11

$`5`
[1] 12 13

$`6`
[1] 14 15 16

В качестве альтернативы вы можете сделать:

split(Transects, cumsum(c(0, diff(Transects)) != 0))
person tmfmnk    schedule 02.07.2020
comment
@ Эндрю Я не уверен, следует ли нам учитывать векторы x и y. Я думаю, что они использовались только для создания вектора Transects. - person tmfmnk; 02.07.2020
comment
Большое спасибо, второй, который возвращает индексы, - это именно то, что я искал! - person Vic; 02.07.2020
comment
Я пытался проголосовать за ваш ответ, но у меня пока недостаточно репутации, чтобы изменить общедоступную оценку, извините. - person Vic; 02.07.2020
comment
Не беспокойтесь об этом, я рад, что это работает для вас :) - person tmfmnk; 02.07.2020

Вы можете использовать функцию map2 из пакета purrr:

муррр::map2(x, y, повтор)

person det    schedule 04.07.2020
comment
Это разбивает куски так, как я хочу, но не дает мне индексы для них, чтобы я мог манипулировать подсчетом отдельных разрезов. - person Vic; 06.07.2020