如何处理R中具有多索引列的数据帧?

时间:2018-06-17 22:10:38

标签: r xts

假设我想研究有关3个生产站点的数量和价格的每日时间序列:我有6个时间序列,我可以存储为带有列的XTS对象 s1.volume, s1.price, s2.volume, s2.price, s3.volume, s3.price

我没有发现任何类似于what I am used to use in Python Pandas的多索引结构。

所以我使用以下方法来处理我的数据:

library(xts)
library(dygraphs)

# Example of original time series
dates <- seq(from = as.POSIXct("2017-01-01"),
             to = as.POSIXct("2017-12-31"),
             by = "day")
N <- length(dates)
data <- data.frame(s1.volume = rnorm(N, 8, 1),
                 s2.volume = rnorm(N, 10, 1),
                 s3.volume = rnorm(N, 12, 1),
                 s1.price = rnorm(N, 110, 10),
                 s2.price = rnorm(N, 100, 10),
                 s3.price = rnorm(N, 90, 10))
tst_xts <- as.xts(data, order.by = dates)

# Example of manipulation to add a new calculated column for each site
sites <- c("s1", "s2", "s3")
volume_cols <- paste(sites, "volume", sep = ".")
price_cols <- paste(sites, "price", sep = ".")
mult_cols <- paste(sites, "mult", sep = ".")
mult_data <- tst_xts[ , volume_cols] * tst_xts[ , price_cols]
colnames(mult_data) <- mult_cols
tst_xts <- merge(tst_xts, mult_data)

# Function to select columns based on "multiindexing" relying on column names
sel_cols <- function(df, indexes, split = "[.]"){
  cols <- colnames(df)
  cols_split <- strsplit(cols, split)
  cols_res <- do.call(rbind, cols_split)
  is_col_sel <- rep(T, length(cols))
  for (i in 1:length(indexes)){
    index <- indexes[i]
    if (index == "") next()
    is_col_sel <- is_col_sel & (cols_res[, i] == index)
  }
  return(is_col_sel)
}

# Example to rescale prices
sel <- sel_cols(tst_xts, c("", "price"))
tst_xts[ , sel] <- tst_xts[ , sel] / 10

# Example to plot all variables for site s1
sel <- sel_cols(tst_xts, c("s1"))
dygraph(tst_xts[ , sel])

这个2级索引示例非常简单,但我经常需要处理4级索引的数据集。

我发现这一切都很乏味,并且想知道是否存在更聪明的结构来处理R中的这种多索引数据。

1 个答案:

答案 0 :(得分:2)

据推测,您只希望能够访问所有s1列,所有s2列,所有s3列或所有卷列,所有价格列或所有多列。

在这种情况下定义a,使得volume / price / mult和s1 / s2 / s3是3d数组的最后两个维度:

ix <- c(matrix(1:9, 3, byrow = TRUE))
dmn <- list(NULL, c("volume", "price", "mult"), c("s1", "s2", "s3"))
a <- array(tst_xts[, ix], c(nrow(tst_xts), 3, 3), dmn)

现在我们已经a我们可以提取它的切片,如果需要,可以将其转换为xts:

vol <- xts(a[, "volume", ], time(tst_xts))

和s1列是:

s1 <- xts(a[,, "s1"], time(tst_xts))

等。或者说,比如10倍的多重卷:

a[, "volume", ] <- 10 * a[, "volume", ]

然后根据需要从卷中创建一个xts对象。