【问题标题】:R - Adding group/condition variables to a time seriesR - 将组/条件变量添加到时间序列
【发布时间】:2017-10-10 13:40:11
【问题描述】:

我有一些来自不同人的生物特征时间序列波形数据,并且一直在使用 zoo 包来存储数据。玩具示例:

library(zoo)
w1 <- sin(seq(0,20,0.25))
w2 <- cos(seq(0,20,0.25))
df <- data.frame(w1,w1,w1,w2,w2,w2)
names(df) <- paste("waves", 1:6, sep="")
waves <- zoo(df)

但我还为每个人提供了一堆额外的组/条件变量(例如,他们的年龄、性别、健康状况)。所以想象一下,如果我现在需要对健康人的波形做点什么。

据我了解,zoo 和 xts 对象都不接受其他变量。所以我的计划是为这些额外的变量维护一个查找数据框。例如:

lookup <- data.frame(index = paste("waves", 1:6, sep=""),
                     group = c("healthy", "unhealthy"))

所以现在,如果我需要对健康人进行抽样,我可以这样做:

select <- waves[, lookup$index[lookup$group=="healthy"]]

有没有更好的方法或数据结构来管理时间序列+附加变量?

【问题讨论】:

  • 您可以在此处使用data.table

标签: r time-series


【解决方案1】:

您正在寻找的是面板数据结构。面板数据,也称为横截面时间序列数据,是随时间和实体变化的数据。在您的情况下,您的waves 中的value 在每个实体内随时间而变化,而group 因实体而异。我们可以做一个简单的gatherjoin 来得到一个典型的面板数据格式。

library(tidyr)
library(dplyr)
panel_df = df %>%
  gather(index, value) %>%
  inner_join(lookup, by = "index") %>%
  group_by(index) %>%
  mutate(time = 1:n())

#     index     value   group  time
#     <chr>     <dbl>   <chr> <int>
# 1  waves1 0.0000000 healthy     1
# 2  waves1 0.2474040 healthy     2
# 3  waves1 0.4794255 healthy     3
# 4  waves1 0.6816388 healthy     4
# 5  waves1 0.8414710 healthy     5
# 6  waves1 0.9489846 healthy     6
# 7  waves1 0.9974950 healthy     7
# 8  waves1 0.9839859 healthy     8
# 9  waves1 0.9092974 healthy     9
# 10 waves1 0.7780732 healthy    10
# # ... with 476 more rows

这里index代表实体维度,我手动创建了一个time变量来表示面板数据的时间维度。

要可视化面板数据,您可以使用ggplot2 执行以下操作:

library(ggplot2)
# Visualize all waves, grouped by health status
ggplot(panel_df, aes(x = time, y = value, group = index)) +
  geom_line(aes(color = group))

# Only Healthy people
panel_df %>%
  filter(group == "healthy") %>%
  ggplot(aes(x = time, y = value, color = index)) +
  geom_line()

# Compare healthy and unhealthy people's waves
panel_df %>%
  ggplot(aes(x = time, y = value, color = index)) +
  geom_line() +
  facet_grid(. ~ group)

使用时间维度:

# plot acf for each entity `value` time series
par(mfrow = c(3, 2))
by(panel_df$value, panel_df$index, function(x) acf(x))

library(forecast)
panel_df %>%
  filter(index == "waves1") %>%
  {autoplot(acf(.$value))}

最后,plm 包非常适合处理面板数据。实现了来自计量经济学的各种面板回归模型,但为了不再给出这个答案,我将留下一些链接供自己研究。 pdim告诉你面板数据的实体和时间维度以及是否平衡:

library(plm)
# Check dimension of Panel
pdim(panel_df, index = c("index", "time"))
# Balanced Panel: n=6, T=81, N=486
  1. What is Panel Data?
  2. Getting Started in Fixed/Random Effects Models using R
  3. Regressions with Panel Data

为了更好的演示,我已经修改了你的数据。

数据:

library(zoo)
w1 <- sin(seq(0,20,0.25))
w2 <- cos(seq(0,20,0.25))
w3 = w1*2
w4 = w2*0.5
w5 = w1*w2
w6 = w2^2

df <- data.frame(w1,w2,w3,w4,w5,w6, stringsAsFactors = FALSE)
names(df) <- paste("waves", 1:6, sep="")
waves <- zoo(df)

lookup <- data.frame(index = paste("waves", 1:6, sep=""),
                     group = c("healthy", "unhealthy"),
                     stringsAsFactors = FALSE)

【讨论】:

  • 哇。感谢您提供超级详细和有用的答案。我真的很感激!
猜你喜欢
  • 2017-02-25
  • 1970-01-01
  • 1970-01-01
  • 2021-11-07
  • 2021-04-26
  • 2021-03-04
  • 1970-01-01
  • 2019-06-22
  • 2013-09-05
相关资源
最近更新 更多