Найти индексы отличные от нуля и посчитать разрывы между вхождениями

У меня есть фрейм данных a с некоторыми 0 и ненулевыми значениями. Например:

0,0,0,30,0,05,0,0,0,0,0,6,0,0,7,0

Я пытался получить ненулевые индексы с помощью which(a!=0) и смог получить 4 6 12 15, Но мой результат должен выглядеть примерно так:

Col1 Col2
 0   -
 0   -
 0   -
 30  4
 0   -
 5   2
 0   -
 0   -
 0   -
 0   -
 0   -
 6   6
 0   -
 0   -
 7   3
 0   -

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

3 ответа

x <- c(0,0,0,30,0,05,0,0,0,0,0,6,0,0,7,0)

Создайте соответствующий вектор:

y <- rep(NA,length(x))

Я заполнил пустые слоты NA; на самом деле невозможно использовать "пустой" заполнитель в числовом столбце. Вы могли бы использовать rep(0,length(x)) (или же numeric(length(x)) вместо.

Найти ненулевые элементы:

nzpos <- which(x!=0)

Заполните ненулевые позиции соответствующими значениями:

y[nzpos] <- c(nzpos[1],diff(nzpos))
data.frame(x,y)

Чтобы получить ожидаемый результат, вы можете просто вычесть полученные значения:

which(a!=0) - c(0, which(a!=0)[-4]) # 4 2 6 3

Затем вы можете создать новый столбец с этими значениями.

a$B <- 0
a$B[which(a!=0)] <- which(a!=0) - c(0, which(a!=0)[-4])

Выход:

    A B
1   0 0
2   0 0
3   0 0
4  30 4
5   0 0
6   5 2
7   0 0
8   0 0
9   0 0
10  0 0
11  0 0
12  6 6
13  0 0
14  0 0
15  7 3
16  0 0

Ты можешь использовать rle возможность подсчета последовательных равных значений:

DF <- data.frame(Col1=c(0,0,0,30,0,05,0,0,0,0,0,6,0,0,7,0),Col2=NA)

# count the length of groups of consecutive zeros
rleRes <- rle(DF$Col1==0)
# we add +1 since we include the next non-zero in the count
counts <- rleRes$lengths[rleRes$values] + 1
# if the last group of zero is not terminated by a non-zero, 
# we don't need to add the last count
if(tail(DF$Col1,1) == 0)
  counts <- counts[-length(counts)]
# if the first value is non-zero, then we need to set Count=0 (or NA) because 
# is not preceded by a group of zero
if(head(DF$Col1,1) != 0)
  counts <- c(0,counts)
# set the count on the second Column
DF$Col2[DF$Col1!=0] <- counts

> DF
   Col1 Col2
1     0   NA
2     0   NA
3     0   NA
4    30    4
5     0   NA
6     5    2
7     0   NA
8     0   NA
9     0   NA
10    0   NA
11    0   NA
12    6    6
13    0   NA
14    0   NA
15    7    3
16    0   NA
Другие вопросы по тегам