【问题标题】:Creating loops across a time series to generate new dataset based on a formula in R在时间序列中创建循环以基于 R 中的公式生成新数据集
【发布时间】:2024-01-19 15:51:01
【问题描述】:

我还没有找到解决 R 中的编码难题的正确方法,希望得到您的帮助。

首先,这是我的大型数据集的一个可重现的小示例:

data <- data.frame(
Date <- sample(c("8/7/2014 23:01", "8/8/2014 10:01", "8/7/2014 11:01", "8/7/2014 12:01", "8/7/2014 13:01")),
`361` <- sample(c("0.035", "0.039", "0.032", "0.042", "0.033")),
`362` <- sample(c("0.038", "0.043", "0.054", "0.023", "0.076")),
`363` <- sample(c("0.038", "0.040", "0.040", "0.020", "0.083")))

我有数百列随后增加的数字,多年来每小时有数千行。

我想要创建一个新的时间序列,为每个列组合采用标准化差异索引 (NDI)。作为参考,NDI 公式为:NDI(a:b) = (x-y)/(x+y)。例如,NDI(361:362) = (xy)/(x+y),并且仅使用第一个日期 8/7/2014 23:01 的值,它将是 NDI(361:362) = (0.035-0.038)/(0.035+0.038) = -0.041。

现在,我想创建一个循环来自动计算 NDI(361:363)、NDI(362:363) 等的所有其余日期和列,输出将放置在其中在新的数据框中。

我们将不胜感激。

感谢您的时间和努力!

【问题讨论】:

  • 在创建循环之前,公式的 R 代码是什么样的?此外,您的可重现示例的代码存在问题。您正在使用sample(),它会创建所提供上下文的随机排列(即,每次运行它都会有所不同,除非您包含种子(例如,set.seed(1)))。我建议删除sample() 函数并将data.frame() 中的&lt;- 更改为=,因为&lt;- 正在将值保存到全局环境中。

标签: r loops automation time-series


【解决方案1】:

我对代码进行了一些快速更改以创建数据框。这是我使用的,希望它仍然能捕捉到你所拥有的:

library(tidyverse)

data <- tibble(
  Date = c("8/7/2014 23:01", "8/8/2014 10:01", "8/7/2014 11:01", "8/7/2014 12:01", "8/7/2014 13:01"),
  `361` = c(0.035, 0.039, 0.032, 0.042, 0.033),
  `362` = c(0.038, 0.043, 0.054, 0.023, 0.076),
  `363` = c(0.038, 0.040, 0.040, 0.020, 0.083), 
  `364` = c(0.034, 0.043, 0.029, 0.019, 0.080)
)

完成这项工作的关键是首先使用combn 识别所有列组合。然后只需将其通过循环,或者在本例中为map 函数。

all_combinations <- combn(names(data)[names(data) != 'Date'], 2) %>%
  as_tibble(.name_repair = 'minimal') %>%
  as.list() %>%
  map_dfc(function(combo) {
    new_column_name <- paste('NDI', combo[1], combo[2], sep = '_')
    data %>%
      mutate(!!new_column_name := (!!sym(combo[1]) - !!sym(combo[2])) / (!!sym(combo[1]) + !!sym(combo[2]))) %>%
      select(last_col())
  })

bind_cols(
  data, 
  all_combinations
)

# A tibble: 5 x 11
  Date           `361` `362` `363` `364` NDI_361_362 NDI_361_363 NDI_361_364 NDI_362_363 NDI_362_364 NDI_363_364
  <chr>          <dbl> <dbl> <dbl> <dbl>       <dbl>       <dbl>       <dbl>       <dbl>       <dbl>       <dbl>
1 8/7/2014 23:01 0.035 0.038 0.038 0.034     -0.0411     -0.0411      0.0145      0           0.0556      0.0556
2 8/8/2014 10:01 0.039 0.043 0.04  0.043     -0.0488     -0.0127     -0.0488      0.0361      0          -0.0361
3 8/7/2014 11:01 0.032 0.054 0.04  0.029     -0.256      -0.111       0.0492      0.149       0.301       0.159 
4 8/7/2014 12:01 0.042 0.023 0.02  0.019      0.292       0.355       0.377       0.0698      0.0952      0.0256
5 8/7/2014 13:01 0.033 0.076 0.083 0.08      -0.394      -0.431      -0.416      -0.0440     -0.0256      0.0184

【讨论】:

  • 嗨,哈里森,很抱歉回复晚了。这是您编写的一段非常优雅和漂亮的代码。我要感谢你花时间帮助我,这意义重大。我想知道你是否得到与我看到的相同的输出。我完全复制了您的代码,对于 all_combinations 输出,日期不会出现在行中。这是可以预期的吗?另外,我会给我的计算机几个小时,但我相信 R 现在正在为我的原始、冗长的数据集运行所有不同的组合。手指交叉。
  • 日期应该出现在行中(请参阅我的更新答案和我的输出)。确保您正在运行所有代码,包括末尾的 bind_cols() 语句。你的原始数据集有多长?最重要的是有多少列?列组合的数量可能很大。
  • 你好。日期确实出现在 tibble 中,但不在 all_combinations 中,这是我希望看到的地方。大约有 4000 行和 300 列。
  • all_combinations 为您提供所有 NDI 结果。如果您只是运行bind_cols(data, all_combinations),那么您将获得原始数据(带有日期) NDI 结果。如果你真的想的话,你甚至可以使用all_combinations &lt;- bind_cols(data, all_combinations) 将它保存回all_combinations
  • 好的,完美!非常感谢您的帮助!
最近更新 更多