使用 tidyr 或 dplyr 重塑数据以用于面板数据研究
Posted
技术标签:
【中文标题】使用 tidyr 或 dplyr 重塑数据以用于面板数据研究【英文标题】:Reshaping data to use for panel data studies, using tidyr or dplyr 【发布时间】:2015-12-17 19:56:04 【问题描述】:我有一个数据框,有 28 行和 26 列。每列代表一天,每一行代表一个时间段t
。它看起来像这样:
dput(head(training_data,10))
structure(list(X11950.0 = c(1L, 15L, 15L, 18L, 31L, 57L, 96L,
134L, 235L, 291L), X11952.0 = c(0L, 15L, 11L, 18L, 45L, 76L,
97L, 115L, 200L, 234L), X11955.0 = c(0L, 13L, 14L, 10L, 30L,
49L, 86L, 114L, 193L, 239L), X11956.0 = c(0L, 15L, 10L, 8L, 38L,
41L, 96L, 117L, 222L, 227L), X11957.0 = c(0L, 10L, 8L, 14L, 33L,
61L, 84L, 143L, 211L, 249L), X11958.0 = c(0L, 18L, 14L, 16L,
48L, 49L, 87L, 117L, 209L, 258L), X11959.0 = c(0L, 14L, 14L,
17L, 33L, 57L, 93L, 100L, 189L, 241L), X11962.0 = c(0L, 8L, 8L,
16L, 29L, 48L, 88L, 126L, 202L, 211L), X11963.0 = c(0L, 8L, 10L,
14L, 44L, 51L, 98L, 148L, 228L, 218L), X11964.0 = c(0L, 15L,
16L, 12L, 39L, 59L, 109L, 138L, 227L, 233L), X11965.0 = c(0L,
14L, 13L, 18L, 34L, 46L, 89L, 154L, 199L, 264L), X11966.0 = c(0L,
18L, 13L, 15L, 37L, 49L, 93L, 142L, 183L, 236L), X11969.0 = c(0L,
7L, 10L, 15L, 34L, 34L, 84L, 136L, 206L, 233L), X11970.0 = c(0L,
12L, 14L, 25L, 36L, 50L, 121L, 145L, 206L, 238L), X11971.0 = c(0L,
17L, 8L, 20L, 36L, 47L, 92L, 108L, 144L, 147L), X12088.0 = c(0L,
5L, 10L, 9L, 35L, 55L, 92L, 112L, 215L, 241L), X12089.0 = c(1L,
8L, 10L, 15L, 15L, 0L, 46L, 118L, 221L, 241L), X12090.0 = c(0L,
8L, 10L, 15L, 46L, 43L, 101L, 106L, 225L, 235L), X12091.0 = c(0L,
5L, 13L, 19L, 40L, 40L, 80L, 119L, 214L, 208L), X12092.0 = c(0L,
9L, 13L, 18L, 41L, 41L, 89L, 100L, 205L, 200L), X12095.0 = c(0L,
8L, 13L, 6L, 32L, 55L, 69L, 112L, 199L, 202L), X12096.0 = c(0L,
7L, 12L, 27L, 40L, 36L, 102L, 119L, 216L, 228L), X12097.0 = c(0L,
9L, 15L, 14L, 43L, 51L, 94L, 122L, 220L, 231L), X12098.0 = c(0L,
10L, 15L, 14L, 47L, 39L, 90L, 117L, 223L, 221L), X12099.0 = c(0L,
9L, 13L, 16L, 39L, 52L, 94L, 110L, 220L, 216L), X12102.0 = c(0L,
9L, 10L, 9L, 51L, 43L, 82L, 98L, 175L, 196L)), .Names = c("X11950.0",
"X11952.0", "X11955.0", "X11956.0", "X11957.0", "X11958.0", "X11959.0",
"X11962.0", "X11963.0", "X11964.0", "X11965.0", "X11966.0", "X11969.0",
"X11970.0", "X11971.0", "X12088.0", "X12089.0", "X12090.0", "X12091.0",
"X12092.0", "X12095.0", "X12096.0", "X12097.0", "X12098.0", "X12099.0",
"X12102.0"), row.names = c(NA, 10L), class = "data.frame")
我正在尝试进行回归分析,在给定日期的每个时间段对其前 3 个值进行回归。为此,我想以这样一种方式修改数据,即对于每一行,第 1 列 yt
将包含时间值 t
,第 2 到第 4 列将包含 y(t-1)
直到 y(t-3)
。
到目前为止我的代码是这样的:
a <- stack(training_data)[,1, drop=FALSE]
panel.data <- read.csv(text="indiv, t, yt, y.t.1, y.t.2, y.t.3",
colClasses = c(integer(), integer(), integer(),
integer(), integer(), integer()),
stringsAsFactors = FALSE )
for(block.id in (0: ((nrow(a)/28) -1)))
# day blocks
block <- a[(28*(block.id)+1) : (28*(block.id+1)), ]
yt <- block[4:28]
first.time.period <- block[3:27]
second.time.period <- block[2:26]
third.time.period <- block[1:25]
insert.block <- c((25*(block.id)+1) : (25*(block.id+1)))
panel.data[insert.block, ]$yt <- yt
panel.data[insert.block, ]$y.t.1 <- first.time.period
panel.data[insert.block, ]$y.t.2 <- second.time.period
panel.data[insert.block, ]$y.t.3 <- third.time.period
再次记住,每天有 28 个时间段。
这行得通,但制作起来很费劲,而且很难看,而且不能真正重复使用。例如,现在我有另一个数据集,看起来像这样,但行数不同,我想将这个表与另一个表连接起来,等等。这很头疼。
我的问题:有没有办法做到这一点,最好是更干净地使用 Hadley 的包(tidyr、dplyr)?我已经研究了这两个,也许spread()
会这样做?我是这些软件包的初学者,即使我已经尝试了几个小时,我仍然无法解决这个问题。
【问题讨论】:
【参考方案1】:这里有一个解决方案。我假设您不想重叠日期(即,第二天第一天的 t-1 不应该是第一天的最后一个时段)。如果不是这种情况,只需删除 group_by()
语句。 slice()
删除每天的前三个句点。
gather(df,day,y) %>%
group_by(day) %>%
mutate(t1=lag(y),
t2=lag(t1),
t3=lag(t2)) %>%
slice(-c(1:3))
【讨论】:
谢谢,它工作得很好!只是几点:1)我可能应该使用滞后而不是领先。 2)如果我使用滞后,我需要每天丢弃结果数据帧的前 3 行。我绝对可以手动完成,只是想知道您的意见 我的错,你确实应该使用滞后。我会编辑这个。它将在找不到任何先前值的地方输出 NA。如果要删除第一行,可以使用 slice()以上是关于使用 tidyr 或 dplyr 重塑数据以用于面板数据研究的主要内容,如果未能解决你的问题,请参考以下文章
通过 dplyr 在第一个遇到的数字上使用单独的(tidyr)分离列
tidyr::spread 和 dplyr::summarise 中的隐式排序