在每个时间单位具有不同观察值的数据框中填写"隐含缺失值"

Lau*_*ler 5 merge r data-manipulation dplyr tidyr

我有一个带有时空数据的大型数据集.每组坐标与id(计算机游戏中的玩家ID)相关联.不幸的是,每个时间单位都没有记录每个id的坐标.如果读取不适用于x时间戳的特定id,则该行完全从数据集中省略,而不是记录为NA.

我希望每个时间单位具有与唯一ID相同的精确观察量(即插入"隐含缺失的NA").在缺少id的时间单位上,应将它们作为新行插入,并以NA作为坐标.

这是一个虚拟数据集来说明:

time <- c(10,10,10,10,11,11,11,11,11,11,12,12,12,12,13,13,14,14,14,14,14,14,15,15,15)
id <- c(1,3,4,5,1,2,3,4,5,6,2,4,5,6,3,6,1,2,3,4,5,6,2,4,5)
x <- c(128,128,64,64,124,128,120,68,64,64,122,71,65,64,112,74,116,114,113,73,70,70,111,75,70)
y <- c(128,128,64,66,125,128,124,66,67,64,124,67,71,68,113,68,115,119,113,76,69,77,116,80,82)

spatiodf <- as.data.frame(cbind(time, id, x, y))


   time id   x   y
1    10  1 128 128
2    10  3 128 128
3    10  4  64  64
4    10  5  64  66
5    11  1 124 125
6    11  2 128 128
7    11  3 120 124
8    11  4  68  66
9    11  5  64  67
10   11  6  64  64
11   12  1 118 123
12   12  2 122 124
13   12  4  71  67
14   12  5  65  71
15   12  6  64  68
16   13  3 112 113
17   13  6  74  68
18   14  1 116 115
19   14  2 114 119
20   14  3 113 113
21   14  4  73  76
22   14  5  70  69
23   14  6  70  77
24   15  2 111 116
25   15  4  75  80
26   15  5  70  82
Run Code Online (Sandbox Code Playgroud)

从上面的输出中我想得到下面的输出,其中重建数据帧,每个时间单元具有相等的观察量(并且NA值被手动插入到具有缺失值的行中).

time <- rep(10:15, each = 6)
id <- rep(1:6, times = 6)
x <- c(128,NA,128,64,64,NA,124,128,120,68,64,64,NA,122,NA,71,65,64,NA,NA,112,NA,NA,74,116,114,113,73,70,70,NA,111,NA,75,70,NA)
y <- c(128,NA,128,64,66,NA,125,128,124,66,67,64,NA,124,NA,67,71,68,NA,NA,113,NA,NA,68,115,119,113,76,69,77,NA,116,NA,80,82,NA)

spatiodf_equal_obs <- as.data.frame(cbind(time, id, x, y))

library(dplyr)
spatiodf_equal_obs %>% 
  arrange(id)

   time id   x   y
1    10  1 128 128
2    11  1 124 125
3    12  1  NA  NA
4    13  1  NA  NA
5    14  1 116 115
6    15  1  NA  NA
7    10  2  NA  NA
8    11  2 128 128
9    12  2 122 124
10   13  2  NA  NA
11   14  2 114 119
12   15  2 111 116
13   10  3 128 128
14   11  3 120 124
15   12  3  NA  NA
16   13  3 112 113
17   14  3 113 113
18   15  3  NA  NA
19   10  4  64  64
20   11  4  68  66
21   12  4  71  67
22   13  4  NA  NA
23   14  4  73  76
24   15  4  75  80
25   10  5  64  66
26   11  5  64  67
27   12  5  65  71
28   13  5  NA  NA
29   14  5  70  69
30   15  5  70  82
31   10  6  NA  NA
32   11  6  64  64
33   12  6  64  68
34   13  6  74  68
35   14  6  70  77
36   15  6  NA  NA
Run Code Online (Sandbox Code Playgroud)

数据需要采用上述格式的原因是因为我希望能够使用相同ID中最近的可用先前或后续条目填充NA值.一旦我们在上面的输出中有数据帧,可以使用来自tidyr的fill()来完成:

library(tidyr)
res <- spatiodf_equal_obs %>%
  group_by(id) %>%
  fill(x, y, .direction = "down") %>%
  fill(x, y, .direction = "up") 
Run Code Online (Sandbox Code Playgroud)

我已经尝试了很多传播,收集(以及创建新数据帧以进行合并(df1,df2,all = TRUE)的技巧).我似乎无法弄清楚如何从第一个数据帧转到第二个数据帧.

最终输出应如下所示:

   time id   x   y
1    10  1 128 128
2    11  1 124 125
3    12  1 124 125
4    13  1 124 125
5    14  1 116 115
6    15  1 116 115
7    10  2 128 128
8    11  2 128 128
9    12  2 122 124
10   13  2 122 124
11   14  2 114 119
12   15  2 111 116
13   10  3 128 128
14   11  3 120 124
15   12  3 120 124
16   13  3 112 113
17   14  3 113 113
18   15  3 113 113
19   10  4  64  64
20   11  4  68  66
21   12  4  71  67
22   13  4  71  67
23   14  4  73  76
24   15  4  75  80
25   10  5  64  66
26   11  5  64  67
27   12  5  65  71
28   13  5  65  71
29   14  5  70  69
30   15  5  70  82
31   10  6  64  64
32   11  6  64  64
33   12  6  64  68
34   13  6  74  68
35   14  6  70  77
36   15  6  70  77
Run Code Online (Sandbox Code Playgroud)

Fra*_*ank 8

要使用从最近一行获取的值填充空白,您可以执行以下操作:

library(data.table)
setDT(spatiodf)

resDT = spatiodf[
  CJ(id = id, time = min(time):max(time), unique = TRUE), on=.(id, time), roll="nearest"
]

# verify
fsetequal(data.table(res), resDT) # TRUE
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  • setDT转换为data.table,因此<-不需要.

  • DT[i, on=, roll=]用于i查找行DT,将每个行滚动i到一行中DT."滚动"在最后一列中完成on=.

  • CJ(a, b, unique = TRUE)返回的所有连击ab一样,expand.grid在基地.