r - 如何处理 R 中具有多索引列的数据帧?
问题描述
假设我想研究关于 3 个生产地点的数量和价格的每日时间序列:我有 6 个时间序列,我可以将它们存储为带有列的 XTS 对象
s1.volume, s1.price, s2.volume, s2.price, s3.volume, s3.price
我没有发现任何类似于我在 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 中的这种多索引数据。
解决方案
大概您只希望能够访问所有 s1 列、所有 s2 列、所有 s3 列或所有量列、所有价格列或所有 mult 列。
在这种情况下,定义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 对象,如图所示。
推荐阅读
- leaflet - 传单如何显示与归属文本内联的地图比例?
- c++ - 合并 2 个已排序的链表
- javascript - 如何使单击单选按钮的行为与单击其容器的行为相同?
- javascript - 反应进度条不是动态的
- javascript - RMarkdown 输出时,.html 文件开头有数千个 JavaScript
- python - 如何将数组中的数字存储在块中并创建另一个数组或列表?
- c# - 我的 .Net Core 应用程序中可以有两种不同类型的 ILogger 吗?
- python-3.x - 通过基于距离对位置进行聚类,以计算成本低廉的方式替代 VRP
- python-3.x - 在定义的符号后向字符串列表添加空格
- scala - 如何在火花结构化流式查询(Kafka)之后调用方法?