【问题标题】:Quickly create new columns in dataframe using lists - R使用列表在数据框中快速创建新列 - R
【发布时间】:2015-08-07 13:28:56
【问题描述】:

我有一个数据,其中包含过去 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 循环或更快地创建这些变量?我读了一些关于应用函数及其派生的东西,但我不知道是否应该以及如何在这里使用它。

我的数据如下所示:

date      CACcloseyesterday CAC1000   CAC1005 ... CACclose ... SP1000 ... SPclose
20140105    3999            4000    40001.2       4005 ....  2000   ....  2003
20140106    4005            4004    40003.5       4002 ....  2005   ....  2002
...

我想要的输出将是一个新列(更确切地说是每次和每个索引的一个新列),它将被添加到 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

【问题讨论】:

  • 如果没有看到您的数据是什么样子以及您想要的输出是什么,就很难回答。你能提供这些吗?
  • 你能显示几行temp
  • 数据是xts对象吗?
  • 如果有帮助,我从 .csv 文件中导入了数据

标签: r for-loop dataframe


【解决方案1】:

看起来您想要生成索引和时间的每个组合。每个索引时间组合都是temp 中的一列,您希望通过将每个索引时间列与特定索引close 列进行比较来计算新的perf 列。而你的问题是你认为应该有一种更简单(不易出错)的方法来做到这一点。

我们可以通过使用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,并直接对那里的两个相关列进行操作。

【讨论】:

  • 感谢您的回答,但我感觉输出不会在列中(我需要一个列来显示 CAC 在 900 时的所有性能,然后是 905,...... MIB 也一样,...)。使用您的解决方案后,是否有一种快速创建这些列的方法?另外,我每天都需要这些结果,但我看不到您的解决方案如何提供每天的结果(顺序很重要)
  • 每一行df 包含一组相关的列名。 temp[[this_row$c1]] &lt;- ... 从其他两列创建一个新列。这和你原来的例子一样。
猜你喜欢
  • 2015-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多