Предыдущие последовательные вхождения во фрейме данных R - PullRequest
0 голосов
/ 07 сентября 2018

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

Мне удалось написать цикл for, чтобы найти предыдущее значение (в моей реальной задаче подмножество данных, следовательно, требуется цикл for).

x<-data.frame(successRate=c(1,1,0,1,0,0,0,1,0,1,1,1,0,1,0,0,0,0,1,1,0,1))


xLength<-length(x$successRate)

y<-vector(mode="integer",length<-xLength)

if (xLength>1){

  for (i in 2:xLength){
    y[i]<-x$successRate[i-1]
  }

}

y[1]<-NA

x[,"previous"]<-y

Однако я ищу желаемый результат следующим образом:

# desired output

data.frame(successRate=c(1,1,0,1,0,0,0,1,0,1,1,1,0,1,0,0,0,0,1,1,0,1),previousConsecutiveSuccess=c(NA,1,2,-1,1,-1,-2,-3,1,-1,1,2,3,-1,1,-1,-2,-3,-4,1,2,-1))

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Пара простых опций:

1) Вариант 1. Использование только базовых функций R, включая rle для кодирования длины серии:

# Your original data.frame
x <- data.frame(successRate=c(1,1,0,1,0,0,0,1,0,1,1,1,0,1,0,0,0,0,1,1,0,1))

# base R method to get lag 1 of a vector
lag_successRate <- c( NA, x$successRate[ - length(x$successRate) ] ) 

lag_rle <- rle(lag_successRate)  # base function for run length encoding

ifelse( lag_rle$values==0, -1, 1 ) * lag_rle$lengths  # multiply the rle length by -1 if the rle value == 0

# output as requested
[1] NA  2 -1  1 -3  1 -1  3 -1  1 -4  2 -1

Вариант 2. Использование data.table, аналогично описанному выше, использование base::rle для получения кодировки длины серии. Если у вас очень большие наборы данных, функции данных data.table, вероятно, будут самыми быстрыми и наиболее эффективными для использования памятью.

# your sample data as a dataframe, as you had originally:
DT <- data.frame(successRate=c(1,1,0,1,0,0,0,1,0,1,1,1,0,1,0,0,0,0,1,1,0,1))

library(data.table)
setDT(DT)  # set DT as a data.table by reference (without any copy!)

lag_rle <- rle( shift(DT$successRate) )  # get rle on the lag 1 of successRate

ifelse( lag_rle$values==0, -1, 1 ) * lag_rle$lengths  # multiply the rle length by -1 if the rle value == 0

# output as requested
[1] NA  2 -1  1 -3  1 -1  3 -1  1 -4  2 -1
0 голосов
/ 07 сентября 2018
x <- data.frame(successRate=c(1,1,0,1,0,0,0,1,0,1,1,1,0,1,0,0,0,0,1,1,0,1))
x$previous <- NA # no need for extra variable

if (nrow(x)>1) {

  # set first consecutive idx manually
  x$previous[2] <- -1+2*x$successRate[1] # -1 if successRate == 0; 1 otherwise

  # loop only if nrow(x) is large enough
  if (nrow(x)>2) {
    for (i in 3:nrow(x)){ # start on row 3, as the last 2 rows are needed
      x$previous[i] <- ifelse(x$successRate[i-1] == x$successRate[i-2], # consecutive?
                              sign(x$previous[i-1])*(abs(x$previous[i-1])+1), # yes: add 1 and keep sign
                              -1+2*x$successRate[i-1])      #  no: 0 -> -1; 1 -> 1
    }
  }
}
print(x$previous)

[1] NA 1 2 -1 1 -1 -2 -3 1 -1 1 2 3 -1 1 -1 -2 -3 -4 1 2 -1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...