Использование матриц cbind и именования временных рядов

Когда cbind Функция используется для объединения 2 или более матриц, результирующая матрица наследует имена столбцов. Простой пример этого факта следующий. У меня есть две (2x2) матрицы m1 а также m2, Колонны m1 являются a а также b; колонны m2 являются c а также d, Если я cbindm1 а также m2Я получаю матрицу с 4 столбцами с именем: a, b, c а также d,

> m1 <- matrix(1:10, ncol = 2)
> colnames(m1) <- letters[1:2]
> m2 <- matrix(11:20, ncol = 2)
> colnames(m2) <- letters[3:4]
> 
> M <- cbind(m1, m2)
> M
     a  b  c  d
[1,] 1  6 11 16
[2,] 2  7 12 17
[3,] 3  8 13 18
[4,] 4  9 14 19
[5,] 5 10 15 20

Тем не менее, я просто понял, что если матрицы m1 а также m2 содержат данные временных рядов, соглашение об именовании для результирующей матрицы после cbind изменения.

> m3 <- ts(m1)
> m4 <- ts(m2)
> M2 <- cbind(m3, m4)
> M2
Time Series:
Start = 1 
End = 5 
Frequency = 1 
  m3.a m3.b m4.c m4.d
1    1    6   11   16
2    2    7   12   17
3    3    8   13   18
4    4    9   14   19
5    5   10   15   20

Как вы можете видеть, имена столбцов M2 начинаются с имен матриц, к которым они изначально принадлежат, и это моя проблема. Я хотел бы сохранить матрицы в формате временных рядов, но избегать нового соглашения об именах. Как я читаю документацию для cbindЯ обнаружил deparse.level аргумент, но это не помогло

M2 <- cbind(m3, m4, deparse.level = 0)
M2

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

> column_names <- c(colnames(m3), colnames(m4))
> colnames(M2) <- column_names
> M2
Time Series:
Start = 1 
End = 5 
Frequency = 1 
  a  b  c  d
1 1  6 11 16
2 2  7 12 17
3 3  8 13 18
4 4  9 14 19
5 5 10 15 20

Ваша помощь очень ценится.

1 ответ

Решение

Прежде всего cbind является универсальной функцией, означающей, что каждый раз, когда вы ее используете, вы используете (немного) другую версию cbind в соответствии с классом объекта (в вашем случае это ts)

Это можно увидеть по:

> library(pryr)
> ftype(cbind)
[1] "internal" "generic" 

А также:

> methods(cbind)
[1] cbind.data.frame cbind.ts*        cbind.zoo  

По сути, каждый раз, когда вы используете cbind с объектом TS вы Cbind вы используете по существу cbind.ts, Давайте посмотрим на исходный код:

> getAnywhere(cbind.ts)
A single object matching ‘cbind.ts’ was found
It was found in the following places
  registered S3 method for cbind from namespace stats
  namespace:stats
with value

function (..., deparse.level = 1) 
{
    if (deparse.level != 1) 
        .NotYetUsed("deparse.level != 1")
    .cbind.ts(list(...), .makeNamesTs(...), dframe = FALSE, union = TRUE)
}
<bytecode: 0x0000000006429410>
<environment: namespace:stats>

Вы можете увидеть выше .NotYetUsed("deparse.level != 1") часть кода. После быстрого просмотра документации о .NotYetUsed показывает, что:

Чтобы точно определить недостающие функциональные возможности, основная команда R использует эти функции для отсутствующих R-функций и еще не использовала аргументы существующих R-функций (которые обычно присутствуют в целях совместимости).

то есть вы не можете использовать deparse.level с чем-либо, кроме 1. И именно поэтому вы получаете "странные" префиксы (имена матриц) в именах ваших столбцов (.makeNamesTs наверное так и делает.

Наконец, чтобы помочь с вашим вопросом (потому что я слишком долго размышлял, я думаю:)), вы можете использовать cbind.data.frame метод для начала на вашем ts объекты, подобные этому (этот метод применяется к матрицам):

> cbind.data.frame(m3,m4)
  a  b  c  d
1 1  6 11 16
2 2  7 12 17
3 3  8 13 18
4 4  9 14 19
5 5 10 15 20

Но вам нужно будет преобразовать это снова в ts, как упомянуло @thelatemail в комментариях к сожалению (так что это не так полезно, я полагаю).

Другие вопросы по тегам