使用列表快速在数据框中创建新列 - R.

时间:2015-08-07 13:28:56

标签: r for-loop dataframe

我有一个数据包含过去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

1 个答案:

答案 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,并直接在那里的两个相关列上进行操作。