Переупорядочить несбалансированные данные временных рядов - PullRequest
0 голосов
/ 28 августа 2018

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

Мои данные выглядят так:

Date         RF   STOCK-A  STOCK-B  STOCK-C  STOCK-D 
1990-11-30   0,03   0,20    0,30     -0,40     0,90
1990-12-31   0,10   0,30    0,30     -0,40     0,34
1991-01-31   0,12   0,90    0,30     -0,60     0,78
1991-02-28   0,03   0,12    0,30       NA      0,50
1991-03-31   0,04   0,14    0,30       NA      0,12
1991-04-30   0,05   0,18    0,30       NA      0,11
1991-05-31   0,03   0,00     NA        NA       NA
1991-06-30   0,00   0,20     NA        NA       NA

Моя проблема в том, что я хочу, чтобы все возвраты акций заканчивались в 1991-06-30 гг., И вместо этого заполняю NA в ранние сроки, чтобы это выглядело так:

 Date         RF   STOCK-A  STOCK-B  STOCK-C  STOCK-D 
1990-11-30   0,03   0,20     NA    -   NA      NA
1990-12-31   0,10   0,30     NA        NA      NA
1991-01-31   0,12   0,90    0,30       NA     0,90
1991-02-28   0,03   0,12    0,30       NA     0,34
1991-03-31   0,04   0,14    0,30       NA     0,78
1991-04-30   0,05   0,18    0,30     -0,40    0,50
1991-05-31   0,03   0,00    0,30     -0,40    0,12 
1991-06-30   0,00   0,20    0,30     -0,60    0,11 

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

data2 <- if (any(is.na(data$STOCK-B))==TRUE){
lag(data$STOCK-B, k= -sum(is.na(data$STOCK-B)))
}else {
any(is.na(data$STOCK-B)==FALSE) 
lag(data$STOCK-B, k=0)
}

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

Я нашел другой метод с пакетом DataCombine:

 Data1 <- slide(data, Var = "data$STOCK-B", slideBy = -sum(is.na(data$STOCK- 
 B)))

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

Заранее спасибо !!

Ответы [ 3 ]

0 голосов
/ 28 августа 2018

Мы можем определить функцию, которая поможет сортировке, а затем использовать mutate_at из пакета dplyr для сортировки каждого столбца.

library(dplyr)

sort_fun <- function(x){
  x_NA <- x[is.na(x)]
  x_non_NA <- x[!is.na(x)]
  x <- c(x_NA, x_non_NA)
  return(x)
}

dat2 <- dat %>%
  mutate_at(vars(-Date), funs(sort_fun(.)))
dat2
#         Date   RF STOCK.A STOCK.B STOCK.C STOCK.D
# 1 1990-11-30 0,03    0,20    <NA>    <NA>    <NA>
# 2 1990-12-31 0,10    0,30    <NA>    <NA>    <NA>
# 3 1991-01-31 0,12    0,90    0,30    <NA>    0,90
# 4 1991-02-28 0,03    0,12    0,30    <NA>    0,34
# 5 1991-03-31 0,04    0,14    0,30    <NA>    0,78
# 6 1991-04-30 0,05    0,18    0,30   -0,40    0,50
# 7 1991-05-31 0,03    0,00    0,30   -0,40    0,12
# 8 1991-06-30 0,00    0,20    0,30   -0,60    0,11

DATA

dat <- read.table(text = "Date         RF   STOCK-A  STOCK-B  STOCK-C  STOCK-D 
1990-11-30   0,03   0,20    0,30     -0,40     0,90
                  1990-12-31   0,10   0,30    0,30     -0,40     0,34
                  1991-01-31   0,12   0,90    0,30     -0,60     0,78
                  1991-02-28   0,03   0,12    0,30       NA      0,50
                  1991-03-31   0,04   0,14    0,30       NA      0,12
                  1991-04-30   0,05   0,18    0,30       NA      0,11
                  1991-05-31   0,03   0,00     NA        NA       NA
                  1991-06-30   0,00   0,20     NA        NA       NA",
                  header = TRUE, stringsAsFactors = FALSE)
0 голосов
/ 28 августа 2018

Я бы использовал функцию apply:

apply(data,2,function(x) as.numeric(x[order(!is.na(x))]))

DATA

data <-structure(list(Date = structure(1:8, .Label = c("1990-11-30", 
"1990-12-31", "1991-01-31", "1991-02-28", "1991-03-31", "1991-04-30", 
"1991-05-31", "1991-06-30"), class = "factor"), RF = c(0.03, 
0.1, 0.12, 0.03, 0.04, 0.05, 0.03, 0), STOCK.A = c(0.2, 0.3, 
0.9, 0.12, 0.14, 0.18, 0, 0.2), STOCK.B = c(0.3, 0.3, 0.3, 0.3, 
0.3, 0.3, NA, NA), STOCK.C = c(-0.4, -0.4, -0.6, NA, NA, NA, 
NA, NA), STOCK.D = c(0.9, 0.34, 0.78, 0.5, 0.12, 0.11, NA, NA
)), class = "data.frame", row.names = c(NA, -8L))
0 голосов
/ 28 августа 2018

Для каждого столбца объедините NA с не-NA:

moveNA <- function(x) c(Filter(is.na, x), na.omit(x))
replace(data, -1, lapply(data[-1], moveNA))

дает:

        Date   RF STOCK.A STOCK.B STOCK.C STOCK.D
1 1990-11-30 0.03    0.20      NA      NA      NA
2 1990-12-31 0.10    0.30      NA      NA      NA
3 1991-01-31 0.12    0.90     0.3      NA    0.90
4 1991-02-28 0.03    0.12     0.3      NA    0.34
5 1991-03-31 0.04    0.14     0.3      NA    0.78
6 1991-04-30 0.05    0.18     0.3    -0.4    0.50
7 1991-05-31 0.03    0.00     0.3    -0.4    0.12
8 1991-06-30 0.00    0.20     0.3    -0.6    0.11

Альтернативой и даже короче moveNA будет:

moveNA <- function(x) x[order(!is.na(x))]

Примечание

Введенное значение data в воспроизводимом виде:

data <-
structure(list(Date = structure(1:8, .Label = c("1990-11-30", 
"1990-12-31", "1991-01-31", "1991-02-28", "1991-03-31", "1991-04-30", 
"1991-05-31", "1991-06-30"), class = "factor"), RF = c(0.03, 
0.1, 0.12, 0.03, 0.04, 0.05, 0.03, 0), STOCK.A = c(0.2, 0.3, 
0.9, 0.12, 0.14, 0.18, 0, 0.2), STOCK.B = c(0.3, 0.3, 0.3, 0.3, 
0.3, 0.3, NA, NA), STOCK.C = c(-0.4, -0.4, -0.6, NA, NA, NA, 
NA, NA), STOCK.D = c(0.9, 0.34, 0.78, 0.5, 0.12, 0.11, NA, NA
)), class = "data.frame", row.names = c(NA, -8L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...