我有一个包含 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)
我有一个包含 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)
通常的答案是通过which.max()
,但是请注意,如果有两个或多个观察值取最大值,这将只返回最大值中的第一个。
另一种方法是which(x == max(x))
,它将返回所有取平局结果中最大值的值。
然后,您可以使用返回的索引来选择系列最大值。处理NA
s 将在下面介绍,以尽量保持最初的讨论简单。
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))
})
由于apply
转换为矩阵,我将使用rollapply
with width=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)