【问题标题】:Subtracting column data in all pair permutations R在所有对排列 R 中减去列数据
【发布时间】:2020-04-17 01:43:57
【问题描述】:

我在数据框中有每小时价格数据,我需要在其中减去所有排列以找到金融交易的最佳配对。每列(不包括价格日期、小时)都可以被视为该股票在特定价格日期和小时内的收盘价。这是数据:

test <- data.frame(pricedate = as.Date('2019-12-18'), hour = c(1,2,3,4,5), A = c(3,5,6,4,2), B = c(5,3,2,6,7), C = c(1,2,3,6,9))

我想获得所有排列组合之间差异的新数据框(或表)。因此,“A减B”不同于“B减A”。而且我不需要从自身中减去一列。结果表如下所示:


Pricedate      Hour        A-B    A-C   B-A    B-C   C-A   C-B 

2019-12-18      1          -2      2     2      4     -2    -4
2019-12-18      2           2      3    -2      1     -3    -1
.
.
.

我认为我需要数据保持这种形式,因为我想在此之后在 R 中计算一些财务统计数据。

【问题讨论】:

标签: r dplyr quantitative-finance tidy


【解决方案1】:

这是一种 tidyverse 方法。首先,我们转换为更长的形式,其中每一列 A:C 表示在一个新行中,并且它来自哪一列的指定进入一个名为“col”的新列。然后我们将该表连接到自身,因此每一行都与共享相同日期和时间的所有行合并。

然后我们计算差异,过滤掉从自身中减去行的行,将两个列标题合并为一个标识列,然后转换回宽格式。

library(tidyverse)

test_longer <- test %>%
  pivot_longer(A:C, names_to = "col", values_to = "val")

test_longer %>%
  left_join(test_longer, 
            suffix = c("1", "2"),
            by = c("pricedate", "hour")) %>%
  filter(col1 != col2) %>%
  mutate(dif = val1 - val2) %>%
  unite("col", c(col1, col2), sep = "-") %>%
  select(-c(val1, val2)) %>%
  pivot_wider(names_from = col, values_from = dif)


# A tibble: 5 x 8
  pricedate   hour `A-B` `A-C` `B-A` `B-C` `C-A` `C-B`
  <date>     <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2019-12-18     1    -2     2     2     4    -2    -4
2 2019-12-18     2     2     3    -2     1    -3    -1
3 2019-12-18     3     4     3    -4    -1    -3     1
4 2019-12-18     4    -2    -2     2     0     2     0
5 2019-12-18     5    -5    -7     5    -2     7     2

【讨论】:

    【解决方案2】:

    我知道您将 dplyrtidy 列为标签,但这里有一个基本方法,可以在整洁的管道中轻松使用:

    somefunc <- function(x) {
      as.data.frame(t(apply(x, 1, function(z) {
        df <- as.data.frame.table(outer(z, z, `-`))
        df <- df[ df[[1]] != df[[2]], ]
        setNames(df[[3]], paste(df[[1]], df[[2]], sep = "_"))
      })))
    }
    somefunc(test[3:5])
    #   B_A C_A A_B C_B A_C B_C
    # 1   2  -2  -2  -4   2   4
    # 2  -2  -3   2  -1   3   1
    # 3  -4  -3   4   1   3  -1
    # 4   2   2  -2   0  -2   0
    # 5   5   7  -5   2  -7  -2
    

    【讨论】:

      【解决方案3】:

      使用combn 的另一种基本 R 方法。由于B-A-(A-B),我们可以使用combn 计算每两个值之间的差异,并通过对计算值求反得到另一个组合。

      cols <- combn(names(test)[3:5], 2, paste, collapse = "-")
      cols <- c(cols, sub("(.)-(.)", "\\2-\\1", cols))
      
      test[cols] <- t(apply(test[3:5], 1, function(x) {
           out <- combn(x, 2, function(x) x[1] - x[2])
           c(out, -out)
      }))
      
      test
      #   pricedate hour A B C A-B A-C B-C B-A C-A C-B
      #1 2019-12-18    1 3 5 1  -2   2   4   2  -2  -4
      #2 2019-12-18    2 5 3 2   2   3   1  -2  -3  -1
      #3 2019-12-18    3 6 2 3   4   3  -1  -4  -3   1
      #4 2019-12-18    4 4 6 6  -2  -2   0   2   2   0
      #5 2019-12-18    5 2 7 9  -5  -7  -2   5   7   2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-21
        • 1970-01-01
        • 1970-01-01
        • 2015-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多