我有一个数据包含过去3年中每5分钟的索引(S& P500,CAC40,...)的引用,这使得它非常庞大。我正在尝试创建包含每次索引性能的新列(即(在[TIME] /报价在昨天结束时报价)-1)和每个索引。我就这样开始了(我的数据名为temp):
listIndexes<-list("CAC","SP","MIB") # there are a lot more
listTime<-list(900,905,910,...1735) # every 5 minutes
for (j in 1:length(listTime)){
Time<-listTime[j]
for (i in 1:length(listIndexes)) {
Index<-listIndexes[i]
temp[[paste0(Index,"perf",Time)]]<-temp[[paste0(Index,Time)]]/temp[[paste0(Index,"close")]]-1
# other stuff to do but with the same concept
}
}
但是很长。有没有办法摆脱for循环或更快地创建这些变量?我读了一些关于apply函数及其衍生物的东西,但我不知道是否以及如何在这里使用它。
我的数据如下:
date CACcloseyesterday CAC1000 CAC1005 ... CACclose ... SP1000 ... SPclose
20140105 3999 4000 40001.2 4005 .... 2000 .... 2003
20140106 4005 4004 40003.5 4002 .... 2005 .... 2002
...
并且我想要的输出将是一个新列(每个时间和每个索引更新eaxcatly一个新列)将被添加到temp
date CACperf1000 CACperf1005... SPperf1000...
20140106 (4004/4005)-1 (4003.5/4005)-1 .... (2005/2003)-1 # the close used is the one of the day before
idem for the following day
我写了(4004/4005)-1只是为了显示计算但结果应该是一个数字:-0.0002496879
答案 0 :(得分:0)
看起来您想要生成索引和时间的每个组合。每个Index-Time组合都是temp
中的一列,您希望通过将每个Index-Time列与特定的Index perf
列进行比较来计算新的close
列。而你的问题是你认为应该有一种更简单(不易出错)的方法。
我们可以通过使用像expand.grid
之类的东西预先生成所有必需的列名来删除其中一个for循环。
listIndexes <-list("CAC","SP","MIB")
listTime <- list(900, 905, 910, 915, 920)
df <- expand.grid(Index = listIndexes, Time = listTime,
stringsAsFactors = FALSE)
df$c1 <- paste0(df$Index, "perf", df$Time)
df$c2 <- paste0(df$Index, df$Time)
df$c3 <- paste0(df$Index, "close")
head(df)
#> Index Time c1 c2 c3
#> 1 CAC 900 CACperf900 CAC900 CACclose
#> 2 SP 900 SPperf900 SP900 SPclose
#> 3 MIB 900 MIBperf900 MIB900 MIBclose
#> 4 CAC 905 CACperf905 CAC905 CACclose
#> 5 SP 905 SPperf905 SP905 SPclose
#> 6 MIB 905 MIBperf905 MIB905 MIBclose
然后只需要一个循环,它用于迭代每批列名并进行计算。
for (row_i in seq_len(nrow(df))) {
this_row <- df[row_i, ]
temp[[this_row$c1]] <- temp[[this_row$c2]] / temp[[this_row$c3]] - 1
}
另一种解决方案也是将您的数据重塑为一种形式,使这种转变更加简单。例如,使用Date,Index,Time,Value,ClosingValue列的列转换为long, tidy format,并直接在那里的两个相关列上进行操作。