Вопрос: Найти начало и конец диапазонов, где данные являются верхним регистром


У меня есть data.frame ystr:

    v1
1    a
2    B
3    B
4    C
5    d
6    a
7    B
8    D

Я хочу найти начало и конец каждой группы букв в CAPS, поэтому мой вывод будет следующим:

    groupId startPos    endPos
1   1       2           4
2   2       7           8

Я смог сделать это с помощью цикла for, посмотрев каждый элемент в порядке и сравнив его с предыдущим следующим образом:

currentGroupId <-0

for (i in 1:length(ystr[,1])){ 
  if (grepl("[[:upper:]]", ystr[i,])) 
  { 
    if (startCounter == 0) 
    {
       currentGroupId <- currentGroupId +1
       startCounter <-1 
       mygroups[currentGroupId,] <- c(currentGroupId, i, 0)
    }
  }else if (startCounter == 1){
    startCounter <-0
    mygroups[currentGroupId,3]<- i-1
  }
}

Есть ли простой способ сделать это в R?

Это может быть похоже на Пометить начало и конец групп  но я не мог понять, как это применимо в этом случае.


4


источник


Ответы:


Вы можете сделать это, вычислив кодировку длины прогона ( rle) бинарного индикатора для того, являются ли ваши данные верхним регистром, как определяется, является ли данные равными себе, когда он преобразуется в верхний регистр.

with(rle(d[,1] == toupper(d[,1])),
     data.frame(start=cumsum(lengths)[values]-lengths[values]+1,
                end=cumsum(lengths)[values]))
#   start end
# 1     2   4
# 2     7   8

Вы можете увидеть другие примеры использования rle взглянув на Ответ на переполнение стека с помощью этой команды ,

Данные:

d <- data.frame(v1=c("a", "B", "B", "C", "d", "a", "B", "D"))

8



Вы можете использовать IRanges пакет. Это в основном найти последовательные диапазоны.

d <- data.frame(v1=c("a", "B", "B", "C", "d", "a", "B", "D"))
d.idx <- which(d$v1 %in% LETTERS)
d.idx
# [1] 2 3 4 7 8

library(IRanges)
d.idx.ir <- IRanges(d.idx, d.idx)
reduce(d.idx.ir)
# IRanges of length 2
#     start end width
# [1]     2   4     3
# [2]     7   8     2

2