r - 从面板格式到宽格式并返回 R data.table:如何保留变量名称?
问题描述
我有一个面板数据集,其中包含大量时间段和单位,以及我为每个时间段和单位观察到的大量变量。
由于我想对每个单位和变量应用单变量时间序列运算,因此我必须将面板数据转换为宽格式(使用 data.table::dcast),以便现在每列显示给定单位的一个变量。
应用我的时间序列观察后,我想回到“长”面板格式(使用 data.table::melt),但是,在这里,我丢失了有关单位名称和变量的信息。由于 data.table 非常大,我害怕在这里混淆数据,这就是为什么我想找到一个保留变量和值名称的熔化操作。
考虑以下示例面板数据集:
require(data.table)
dates <- seq(from = as.Date("2007-02-01"), to = as.Date("2012-01-01"), by = "month")
id <- paste0(c("A", "B", "C"), 1:10)
DT <- data.table(
time = rep(dates, 10),
idx = rep(id, each = 60),
String1 = runif(600),
String2 = runif(600),
String3 = runif(600)
)
time idx String1 String2 String3
1: 2007-02-01 A1 0.5412122 0.23502234 0.3858354
2: 2007-03-01 A1 0.3248168 0.32884580 0.7183147
3: 2007-04-01 A1 0.4183034 0.40781723 0.7438458
4: 2007-05-01 A1 0.3597997 0.51745402 0.1660566
5: 2007-06-01 A1 0.6405351 0.96121729 0.7786483
---
596: 2011-09-01 A10 0.7896711 0.64740298 0.8285408
597: 2011-10-01 A10 0.6582652 0.83986453 0.1292342
598: 2011-11-01 A10 0.1110465 0.41741672 0.7076345
599: 2011-12-01 A10 0.5108850 0.02940229 0.9038370
600: 2012-01-01 A10 0.2605052 0.10136480 0.3881788
我将此面板数据集转换为宽格式。在应用了一些时间序列操作(此处未显示)之后,如果没有足够的数据,我将不得不删除一些列。然后,我将数据恢复为长格式
variable_names <- names(DT[,-c("time", "idx")])
DT_long <- dcast(DT, time ~ idx, value.var = variable_names)
DT_long <- DT_long[,-(5:10)]
DT_wide <- melt(DT_long, measure = patterns("^String1", "^String2", "^String3"), value.name = variable_names, variable.name = "idx)
time idx String1 String2 String3
1: 2007-02-01 1 0.9794707 0.5290352 0.68009050
2: 2007-03-01 1 0.4016173 0.9229200 0.38652407
3: 2007-04-01 1 0.9475505 0.5956701 0.24686007
4: 2007-05-01 1 0.6465847 0.8233340 0.08008369
5: 2007-06-01 1 0.5704834 0.8232598 0.85790038
---
596: 2011-09-01 10 NA 0.5525413 0.79994190
597: 2011-10-01 10 NA 0.3895864 0.41347910
598: 2011-11-01 10 NA 0.3123646 0.44461146
599: 2011-12-01 10 NA 0.2148686 0.37609448
600: 2012-01-01 10 NA 0.7314114 0.47138012
DT_wide 现在看起来像这样,这意味着我丢失了有关变量(此处为:idx)名称的信息。我想的一个解决方法是用数字对所有 idx 进行编号,然后执行此操作。但是,如果可能的话,我想保留字符串名称,因为它们有助于我区分和理解这些值。有人可以帮助我如何重写融化以包含这些信息吗?
解决方案
通读?melt
和高效重塑小插图,我看不出如何直接使用melt.data.table
. 但是,您可以pivot_longer()
从tidyr的开发版本中使用:
library(data.table)
dates <- seq(from = as.Date("2007-02-01"), to = as.Date("2007-04-01"), by = "month")
id <- c("A1", "B2")
DT <- data.table(
time = rep(dates, 2),
idx = rep(id, each = 3),
String1 = runif(6),
String2 = runif(6)
)
DT
#> time idx String1 String2
#> 1: 2007-02-01 A1 0.6453802 0.4641508
#> 2: 2007-03-01 A1 0.1106000 0.3750282
#> 3: 2007-04-01 A1 0.6356700 0.9601759
#> 4: 2007-02-01 B2 0.9821609 0.1782534
#> 5: 2007-03-01 B2 0.4786173 0.1557481
#> 6: 2007-04-01 B2 0.7720111 0.7982246
variable_names <- names(DT[, -c("time", "idx")])
DT_long <- dcast(DT, time ~ idx, value.var = variable_names)
DT_long
#> time String1_A1 String1_B2 String2_A1 String2_B2
#> 1: 2007-02-01 0.6453802 0.9821609 0.4641508 0.1782534
#> 2: 2007-03-01 0.1106000 0.4786173 0.3750282 0.1557481
#> 3: 2007-04-01 0.6356700 0.7720111 0.9601759 0.7982246
library(tidyr) # devtools::install_github("tidyverse/tidyr")
pivot_longer(
data = DT_long,
cols = starts_with("String"),
names_sep = "_",
names_to = c(".value", "idx")
)
#> # A tibble: 6 x 4
#> time idx String1 String2
#> <date> <chr> <dbl> <dbl>
#> 1 2007-02-01 A1 0.645 0.464
#> 2 2007-02-01 B2 0.982 0.178
#> 3 2007-03-01 A1 0.111 0.375
#> 4 2007-03-01 B2 0.479 0.156
#> 5 2007-04-01 A1 0.636 0.960
#> 6 2007-04-01 B2 0.772 0.798
由reprex 包(v0.3.0)于 2019 年 9 月 9 日创建
推荐阅读
- ios - Firebase AB 测试的变体不成比例
- python - 来自 csv 文件的两个特定列的列表字典
- angular - 如何从组件配置 routerLink
- c# - C# 在 XML 中查找具有给定属性名称的节点
- sql-server - 如何从另一个容器连接到 SQL Server docker 容器?
- php - 带有 php exec 的 Crontab
- sql - 查询以包括当天+第二天直到特定时间的所有交易
- android - 从流 mp3 url 中检索图像
- php - jQuery click 函数只显示页面上的第一个值
- java - 我对如何运行 springboot 项目有疑问