使用 cbind 和命名时间序列矩阵
Using cbind and naming time series matrices
当cbind
函数用于合并2个或更多矩阵时,生成的矩阵会继承列名。这个事实的一个简单例子如下。我有两个 (2x2) 矩阵 m1
和 m2
。 m1
的列是a
和b
; m2
的列是 c
和 d
。如果我 cbind
m1
和 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
非常感谢您的帮助。
首先,cbind
是一个通用函数,这意味着每次使用它时,都会根据对象的 class(在您的情况下为 ts)使用(略有)不同版本的 cbind )
这可以通过以下方式看到:
> 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
的文档后发现:
In order to pinpoint missing functionality, the R core team uses these functions for missing R functions and not yet used arguments of existing R functions (which are typically there for compatibility purposes).
即您不能将 deparse.level
与 1 以外的任何其他内容一起使用。这就是为什么您在列名称中获得 'strange' 前缀(矩阵名称)的原因(.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 在评论中提到的那样(所以我认为这没有多大帮助)。
当cbind
函数用于合并2个或更多矩阵时,生成的矩阵会继承列名。这个事实的一个简单例子如下。我有两个 (2x2) 矩阵 m1
和 m2
。 m1
的列是a
和b
; m2
的列是 c
和 d
。如果我 cbind
m1
和 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
非常感谢您的帮助。
首先,cbind
是一个通用函数,这意味着每次使用它时,都会根据对象的 class(在您的情况下为 ts)使用(略有)不同版本的 cbind )
这可以通过以下方式看到:
> 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
的文档后发现:
In order to pinpoint missing functionality, the R core team uses these functions for missing R functions and not yet used arguments of existing R functions (which are typically there for compatibility purposes).
即您不能将 deparse.level
与 1 以外的任何其他内容一起使用。这就是为什么您在列名称中获得 'strange' 前缀(矩阵名称)的原因(.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 在评论中提到的那样(所以我认为这没有多大帮助)。