使用cbind和命名时间序列矩阵

时间:2015-04-08 22:38:48

标签: r cbind

cbind函数用于组合2个或更多矩阵时,生成的矩阵会继承列名。这个事实的一个简单例子如下。我有两个(2x2)矩阵m1m2m1的列为ab; m2的列为cd。如果我cbind m1m2,我会获得一个包含4列的矩阵:abc和{{1} }。

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

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

首先,cbind是一个通用函数,意味着每次使用它时,根据对象的类(在您的情况下为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的文档后会发现:

  

为了查明缺失的功能,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

但不幸的是,你需要将@thelatemail在评论中再次转换为ts(所以我认为这没有用)。