Как определить переменную запаздывания на основе заранее определенной последовательности - PullRequest
0 голосов
/ 23 октября 2019

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

Моя проблема в том, что для начального года временного ряда я получаю NA, когда генерирую переменную с задержкой. Содержимое value следует повторяющемуся шаблону, но этот шаблон отличается на id.

Теоретически, нужно иметь возможность сопоставить шаблон с наблюдаемой последовательностью value и использовать известный шаблон длязаполните NA в переменной lagged, но я не могу понять, как подойти к этой проблеме.

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

data <- tibble(
  year=rep(2015:2018,3),
  id=c(rep('A',4),rep('B',4),rep('C',4)),
  value=c('CG','SB','CG','CG',
          'CG','CG','CG','CG',
          'CG','SB','CG','SB')
)

data.seq <- tibble(
  seq1=c('CG','CG','SB'),
  seq2=c('CG','CG',NA),
  seq3=c('CG','SB',NA)
)

# Generate new variable that has 'value' of previous year
data <- data %>% 
  group_by(id) %>%
  mutate(
    lagValue = lag(value)
  )

# Need to fill in the NA's based on the sequences in data.seq

Чтобы помочь ответить на вопрос, я ввел вручнуюкаким должен быть вывод для NA, заданных последовательностями в data.seq:

expected.data <- data
expected.data[c(1,5,9),'lagValue'] <- c('CG','CG','SB')

1 Ответ

0 голосов
/ 23 октября 2019

Я создал своего рода функцию сортировки для вашего использования.

library(tidyverse)

data <- tibble(
  year = rep(2015:2018, 3),
  id = c(rep('A', 4), rep('B', 4), rep('C', 4)),
  value = c(
    'CG',
    'SB',
    'CG',
    'CG',
    'CG',
    'CG',
    'CG',
    'CG',
    'CG',
    'SB',
    'CG',
    'SB'
  )
)

# lookup list for ids and sequence
data.seq <- list()
data.seq$A <- c('CG', 'CG', 'SB')
data.seq$B <- c('CG', 'CG')
data.seq$C <- c('CG', 'SB')


findPos <- function(value, group) {

  # select sequence according to group
  currentSeq <- data.seq[[unique(group)]]

  # get rid of NAs
  seqMatch <- currentSeq[!is.na(currentSeq)]

  # multiplier for sequence
  compareLength <- length(value) + length(seqMatch) - 1

  multi <- compareLength / length(seqMatch)
  mod <- compareLength %% length(seqMatch)

  if (mod > 0) {
    multi <- as.integer(multi) + 1

  }

  # multiple sequence
  seqMatch <- rep(seqMatch, multi)

  i <- 1
  # search und rotate position until match is found
  repeat {
    if (identical(lag(value)[!is.na(lag(value))], 
                  seqMatch[i:(length(value) - 2 + i)])) {

      # if found on first position, add another sequence at the beginning
      if (length(seqMatch[i - 1]) == 0) {
        return(c(currentSeq, seqMatch)[length(currentSeq)+i-1])

      } else {
        return(seqMatch[i - 1])
      }

    }

    i <- i + 1

  }

}

data <- data %>%
  group_by(id) %>%
  mutate(lagValue = ifelse(is.na(lag(value)), 
                           findPos(value, id), 
                           lag(value)))


...