用虚拟零填充时间序列数据帧

时间:2018-06-12 11:31:27

标签: r dplyr tidyr

我想这是一个非常简单的问题,但是我无法理解它。

考虑这个数据框:

df <- data.frame(            
week = c(1,1,1,2,3,3,3),     
id = c(12,13,14,12,12,13,14),
x = sample(c(100:200), 7))   
df                           
#>   week id   x
#> 1    1 12 126
#> 2    1 13 166
#> 3    1 14 129
#> 4    2 12 128
#> 5    3 12 136
#> 6    3 13 120
#> 7    3 14 115

我想在第2周为NA创建一个虚拟值0或x,其中id 13和14没有观察结果。换句话说:这样{x = 0 1}}适用于第2周id 13和14.最好使用dplyr

关于如何做到这一点的任何想法?

1 个答案:

答案 0 :(得分:2)

虽然此问题被标记为重复使用group by,但此处并不需要。我们还添加了动物园和几个基本答案。

1)在tidyr中完成(tidyr) complete

library(tidyr)

complete(DF, week, id)

,并提供:

# A tibble: 9 x 3
   week    id     x
  <int> <int> <int>
1     1    12   126
2     1    13   166
3     1    14   129
4     2    12   128
5     2    13    NA
6     2    14    NA
7     3    12   136
8     3    13   120
9     3    14   115

2)read.zoo / fortify.zoo(zoo)在星期创建一个动物园对象,然后使用melt=TRUE将其转换回data.frame:

library(zoo)

z <- read.zoo(DF, index = "id", split = "week")
fortify.zoo(z, melt = TRUE, names = names(DF)[c(2:1, 3)])

,并提供:

  id week   x
1 12    1 126
2 13    1 166
3 14    1 129
4 12    2 128
5 13    2  NA
6 14    2  NA
7 12    3 136
8 13    3 120
9 14    3 115

3)重塑(基础)重塑为宽形式,然后返回长形式:

wide <- reshape(DF, idvar = "week", timevar = "id", dir = "wide")
long <- reshape(wide, dir = "long")

names(long) <- names(DF)

4)tapply / as.data.frame.table(base)

as.data.frame.table(tapply(DF[[3]], DF[-3], c), responseName = names(DF)[3])

5)expand.grid / merge(base)

with(DF, merge(expand.grid(week = unique(week), id = unique(id)), DF, all = TRUE))