2

当该cbind函数用于组合 2 个或更多矩阵时,生成的矩阵会继承列名。下面是一个简单的例子。我有两个 (2x2) 矩阵m1m2. 的列m1ab; 的列m2cd。如果 Icbind m1和,我得到一个包含 4 列的m2矩阵:ab和。cd

> 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

但是,我刚刚意识到,如果矩阵m1m2包含时间序列数据,则生成的矩阵的命名约定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

非常感激您的帮忙。

4

1 回答 1

5

首先cbind是一个通用函数,这意味着每次使用它时,您都会根据对象的类(在您的情况下为 ts)使用(略微)不同版本的 cbind

这可以通过以下方式看到:

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

和:

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

所以基本上每次你使用cbindts 对象时,你使用的 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 (所以我认为它没有那么有用)。

于 2015-04-08T23:06:14.797 回答