1

我想将唯一的数字因子作为 xts 的一部分,以便随着时间的推移......每个数字都指一个特定的因子,与时间无关。

举个例子,想象一个股票指数每天都在变化。如果我有以下两个字母股票代码的宇宙,我们可以模拟这一点

universe <- apply(as.data.frame(expand.grid(letters,letters)),1,paste0,collapse="")

并且每天都会创建一个指数,该指数是来自宇宙的 20 个股票代码的随机子样本。

subsample.list <- lapply(1:50, function(y){
     sort(sample(universe,20,replace=FALSE))
 })

50天独特股票的关键是:

uni.subsample <- sort(unique(unlist(subsample.list)))

如果我有 xts 对象和独特的因素,我希望基本上每天都能看到指数中有哪些股票。

虽然它不应该以这种方式使用....我在想这样的事情:

tmp <- xts(do.call(rbind,subsample.list),Sys.Date()-c(50:1))

创建 xts。

但是我想将 coredata 转换为一个数字矩阵,其中每个数字都是来自uni.subsample

所以如果tmp.adjusted['20130716'][1,]是长度为 20 的数字的数字向量,它代表 2013 年 7 月 16 日的数值uni.subsample,所以我希望我能够通过使用 xts 来获取所有 2013-07-16 的索引成员以下方式uni.subsample[tmp.adjusted['20130716'][1,]]...即从 tmp 到 tmp.adjusted 的调整将字符串转换为因子,具有与相关的唯一级别uni.subsample

我希望这是有道理的……有点难以解释……

4

2 回答 2

3

这是一个矢量化的解决方案:

   tmp.int <- xts(matrix(as.integer(factor(tmp,levels=uni.subsample,ordered=TRUE)),
          ncol=ncol(tmp)),index(tmp))

您基本上是在尝试按级别顺序编写有序因子矩阵。

编辑添加一些基准测试:

set.seed(1233)
N <- 5000
subsample.list <- lapply(seq(N), function(y){
  sort(sample(universe,20,replace=FALSE))
})
uni.subsample <- sort(unique(unlist(subsample.list)))
tmp <- xts(do.call(rbind,subsample.list),Sys.Date()-seq(N))
ag <- function() xts(matrix(as.integer(factor(tmp,levels=uni.subsample,ordered=TRUE)),
                      ncol=ncol(tmp)),index(tmp))
no <- function()xts(apply(X=tmp, 
                          MARGIN=c(1,2), function(x) which(uni.subsample == x)),
               index(tmp))
library(microbenchmark)
microbenchmark(ag(),no(),times=1)

## N = 50 ag 24 faster
microbenchmark(ag(),no(),times=1)
Unit: milliseconds
 expr       min        lq    median        uq       max neval
 ag()  1.126405  1.126405  1.126405  1.126405  1.126405     1
## N = 500 ag 135 fatser
microbenchmark(ag(),no(),times=10)
Unit: milliseconds
 expr        min         lq     median         uq        max neval
 ag()   23.38484   26.19744   31.13428   35.51057   44.96251    10
 no() 3115.24902 3220.04940 3250.63773 3288.66867 3470.35053    10
     no() 24.000003 24.000003 24.000003 24.000003 24.000003     1
于 2013-07-16T15:06:11.997 回答
1

怎么样:

tmp.int <- xts(apply(X=tmp, MARGIN=c(1,2), function(x) which(uni.subsample == x)),
    index(tmp))

# to perform the lookup (e.g., 'find the name of the first value on May 27, 2013'):
uni.subsample[tmp.int['2013-05-27'][,1]]
于 2013-07-16T14:26:39.277 回答