Найти индексы отличные от нуля и посчитать разрывы между вхождениями
У меня есть фрейм данных 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