Создайте временной ряд, используя диагональные матрицы - PullRequest
2 голосов
/ 29 апреля 2020

Допустим, мои данные имеют следующую структуру:

structure(list(Year = c(2000, 2000, 2000, 2000, 2000, 2000, 2000, 
2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 
2000, 2000, 2001, 2001, 2001, 2001), Month = c(1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), Day = c(1, 
1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 1, 1, 
1, 1), FivMin = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 
4, 1, 2, 3, 4, 1, 2, 3, 4), A = c(1, 2, 3, 0, 1, 5, 3, 4, 1, 
0, 3, 1, 0, 2, 3, 0, 1, 2, 0, 9, 1, 2, 3, 0), B = c(2, 3, 4, 
1, 2, 3, 0, 1, 2, 1, 4, -2, 2, 1, 0, 2, 2, 3, -1, 1, 2, 3, 4, 
1), C = c(3, 0, 1, 2, 3, 4, 1, 9, 3, 7, 1, 2, 3, 4, 1, 2, 3, 
4, 1, 2, 3, 0, 1, 2), D = c(4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 
3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3)), row.names = c(NA, -24L
), class = c("tbl_df", "tbl", "data.frame"))

Моя идея - использовать команду crossproduct каждый день. Чтобы сделать это, я написал следующий код:

res <- lapply(split(data, data[c("Year","Month","Day")]), 
          function(x) tcrossprod(t(x[c("A","B","C","D")])))
Final<-do.call(rbind, lapply(res, diag))

Вывод Final:

          A  B   C  D
2000.1.1 14 30  14 30
2001.1.1 14 30  14 30
2000.1.2 51 14 107 30
2001.1.2  0  0   0  0
2000.1.3 11 25  63 30
2001.1.3  0  0   0  0
2000.1.4 13  9  30 30
2001.1.4  0  0   0  0
2000.1.5 86 15  30 30
2001.1.5  0  0   0  0 

Мне нужно время ser ie (матрица или объект df) ), образованный диагоналями, рассчитанными с помощью crossproduct, это означает, что желаемое время ser ie будет

          A  B   C  D
2000.1.1 14 30  14 30
2000.1.2 51 14 107 30
2000.1.3 11 25  63 30
2000.1.4 13  9  30 30
2000.1.5 86 15  30 30
2001.1.1 14 30  14 30

Каковы будут изменения в моем исходном коде. Я думаю, что я мог бы заменить команду split на grouped_by, но она не сработала.

1 Ответ

1 голос
/ 29 апреля 2020

Поскольку разделение превращает фрейм данных в список, оно также создает 0 строк. Просто удалите эти нулевые строки и попробуйте.

ls<- split(data, data[c("Year","Month","Day")])
ls<- ls[sapply(ls, nrow)>0]
res <- lapply(ls, function(x) tcrossprod(t(x[c("A","B","C","D")])))
Final<-do.call(rbind, lapply(res, diag))
Final <- Final[ order(row.names(Final)), ]
Final

Вывод:

          A  B   C  D
2000.1.1 14 30  14 30
2000.1.2 51 14 107 30
2000.1.3 11 25  63 30
2000.1.4 13  9  30 30
2000.1.5 86 15  30 30
2001.1.1 14 30  14 30
...