当我按行应用时,如何获取多系列动物园对象的列名(或数字)?

时间:2013-07-22 16:06:31

标签: r time-series zoo

我有一套动物园对象,每月有12套股票代号。我想得到符号,这是每个月表现最好的股票的系列名称,或者至少是列。我一直试图通过行应用max函数来做到这一点。如何获取列名?

#Apply 'max' function across each row. I need to get the col number out of this.
apply(tsPctChgs, 1, max, na.rm = TRUE)

2 个答案:

答案 0 :(得分:4)

通常的答案是通过which.max(),但是请注意,如果有两个或更多观察值采用最大值,这将仅返回最大值中的第一个。

另一种选择是which(x == max(x)),它会返回所有值,并在平局结果中取最大值。

然后,您可以使用返回的索引来选择最大系列。下面将介绍处理NA以尽量简化初始讨论。

require("zoo")
set.seed(1)
m <- matrix(runif(50), ncol = 5)
colnames(m) <- paste0("Series", seq_len(ncol(m)))
ind <- seq_len(nrow(m))

mz <- zoo(m, order.by = ind)

> apply(mz, 1, which.max)
 1  2  3  4  5  6  7  8  9 10 
 3  5  5  1  4  1  1  2  3  2

> apply(mz, 1, function(x) which(x == max(x)))
 1  2  3  4  5  6  7  8  9 10 
 3  5  5  1  4  1  1  2  3  2

所以用它来选择系列名称

i1 <- apply(mz, 1, function(x) which(x == max(x)))
colnames(mz)[i1]

> i1 <- apply(mz, 1, function(x) which(x == max(x)))
> colnames(mz)[i1]
 [1] "Series3" "Series5" "Series5" "Series1" "Series4" "Series1" "Series1"
 [8] "Series2" "Series3" "Series2"

处理绑定的最大值

为了说明不同的行为,请将第1个月(系列3)的最大值复制到系列1

mz2 <- mz ## copy
mz2[1,1] <- mz[1,3]
mz2[1,]

> mz2[1,]

1 0.9347052 0.2059746 0.9347052 0.4820801 0.8209463

现在再试一次这两种方法

> apply(mz2, 1, which.max)
 1  2  3  4  5  6  7  8  9 10 
 1  5  5  1  4  1  1  2  3  2 
> apply(mz2, 1, function(x) which(x == max(x)))
$`1`
Series1 Series3 
      1       3
.... ## truncated output ###

请注意which.max仅返回系列1中的最大值。

要使用此方法选择系列名称,您需要将某些内容应用于apply()返回的列表,例如

i2 <- apply(mz2, 1, function(x) which(x == max(x)))
lapply(i2, function (i, zobj) colnames(zobj)[i], zobj = mz2)

$`1`
[1] "Series1" "Series3"

$`2`
[1] "Series5"

$`3`
[1] "Series5"

$`4`
[1] "Series1"

$`5`
[1] "Series4"

$`6`
[1] "Series1"

$`7`
[1] "Series1"

$`8`
[1] "Series2"

$`9`
[1] "Series3"

$`10`
[1] "Series2"

处理NA s

由于你有NA的潜力,我会做以下事情:

apply(mz, 1, which.max, na.rm = TRUE) ## as you did already
apply(mz, 1, function(x, na.rm = TRUE) {
               if(na.rm) {
                 x <- x[!is.na(x)]
               }
               which(x == max(x))
             })

答案 1 :(得分:3)

由于apply转换为矩阵,我会将rollapplywidth=1一起使用:

require("zoo")
set.seed(1)
m <- matrix(runif(50), ncol=5)
mz <- setNames(zoo(m, seq(nrow(m))), paste0("Series",seq(ncol(m))))
rollapply(mz, 1, function(r) colnames(mz)[which.max(r)], by.column=FALSE)