在时间序列中创建循环以根据 R 中的公式生成新数据集
Creating loops across a time series to generate new dataset based on a formula in R
我一直无法找到解决 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) = (x-y)/(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) 等所有其余日期和列,其中输出将被放置在一个新的数据框中。
我们将不胜感激任何帮助。
感谢您的时间和努力!
我对代码进行了一些快速更改以创建数据框。这就是我使用的,希望它仍然能捕捉到你所拥有的:
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
我一直无法找到解决 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) = (x-y)/(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) 等所有其余日期和列,其中输出将被放置在一个新的数据框中。
我们将不胜感激任何帮助。
感谢您的时间和努力!
我对代码进行了一些快速更改以创建数据框。这就是我使用的,希望它仍然能捕捉到你所拥有的:
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