在列表的一列中排名

ranking across a column of a list

我有一个包含各种符号的列表,我想为其创建一个列并相对于列表的其余部分对特定列进行排名。

例如,我有一个列表x,其中包含SPYIWM的时间序列。对于每个列表项,我计算 rsi。然后我想在每个列表中创建一个新列,为 SPYIWM 之间的最低 rsi 值分配一个等级。

我总是得到 1 的排名,这不可能是正确的,所以我的代码一定有问题。正如我所说,我需要 rsi 的等级。

library(quantmod)

stockData <- new.env() 

symbols = c("IWM","SPY")
getSymbols(symbols, src='yahoo',from = "2016-10-01",to = Sys.Date())


x <- list() 
for (i in 1:length(symbols)) {
  x[[i]] <- get(symbols[i], pos=stockData)  # get data from stockData environment 
  x[[i]]$rsi <-RSI(Cl(x[[i]]),14)
  x[[i]]$rank <- NA
  x[[i]]$rank<-apply(-x[[i]]$rsi,1,rank)
}
library(quantmod)
stockData <- new.env() 

symbols = c("IWM","SPY")
getSymbols(symbols, src='yahoo',from = "2016-10-01",to = Sys.Date())

fulldata <- lapply(symbols, get, pos = stockData)
closedata <- lapply(fulldata, Cl)
rsi <- lapply(closedata, RSI, n = 14) # or e.g. n = 2, if RSI based on two periods  

为了稍后使用排名,我们需要将数据转换为 data.frame,因为 rank() 不喜欢 [=18] 输出的 class =] 给出。

rsi <- lapply(rsi, as.data.frame)

RSI()取决于14个周期的移动平均数,导致前14个周期的结果为NA,因为它们无法计算移动平均数。

在进行排名时,有几个选项可以处理 NA 值。您认为最合适的选项将取决于您以后要将数据用于什么目的:

  • 您可以选择将 rsi 中的所有 NA 值替换为零排名:

    for(i in 1:length(rsi)){
        rsi[[i]][is.na(rsi[[i]])] <- 0
        }
    ranks <- lapply(rsi, rank)
    
  • 您可以忽略所有 NA 值并在排名前简单地删除它们

     ranks <- lapply(rsi, rank, na.last = NA)
    
  • NA 值列为最低或最高排名。

    # If NA be put last, use "na.last = TRUE".
    # If NA be put first, use "na.last = FALSE"
    ranks <- lapply(rsi, rank, na.last = TRUE)  
    

给定日期 个符号中的排名

我会将列表组合成一个数据框,然后计算按行排序:

rsiDF <- data.frame(rsi)
rsiDF <- cbind(rsiDF, t(apply(rsiDF, 1, rank)))

请注意,在这里您可以再次决定如何在排名计算中处理绑定值和 NA 值(如上文和 ?rank 中所述)

如果您想再次将其转回列表:

k <- length(symbols)
interranks <- list()
for(i in 1:k){
   interranks[[i]] <- rsiDF[,c(i, i+k)]
}