【问题标题】:Create a sequential number within each group在每个组中创建一个序号
【发布时间】:2021-02-11 21:25:27
【问题描述】:

我需要根据另一列创建一个数字序列

我有这个数据框:

head(df)
        id                date      lc     lon     lat   gap_days  gap
1 20162.03 2003-10-19 14:33:00 Tagging -39.370 -18.480         NA <NA>
2 20162.03 2003-10-21 12:19:00       1 -38.517 -18.253 1.90694444  gap
3 20162.03 2003-10-21 13:33:00       1 -38.464 -18.302 0.05138889   no
4 20162.03 2003-10-21 16:38:00       A -38.461 -18.425 0.12847222   no
5 20162.03 2003-10-21 18:50:00       A -38.322 -18.512 0.09166667   no
6 20162.03 2003-10-23 10:33:00       B -38.674 -19.824 1.65486111  gap

我根据 gap_days 列在“gap”列中指出了超过 1 天的间隔。 现在,我需要拆分我的数据。每个间隙序列都将是一个新的单独帧。

所以,如果我有 ID 20162.03,并且这个 id 有一个或多个间隙,这个序列将根据间隙的数量进行拆分。 为此,我将使用包 move 和函数 burst" 和 split

但是,为此我需要创建一个新列,其中包含一系列数字来指示新的 id 分离,如(seq 列):

id                date              lc     lon     lat    gap_days  gap seq
1 20162.03 2003-10-19 14:33:00 Tagging -39.370 -18.480         NA <NA>   1
2 20162.03 2003-10-21 12:19:00       1 -38.517 -18.253 1.90694444  gap   1
3 20162.03 2003-10-21 13:33:00       1 -38.464 -18.302 0.05138889   no   1
4 20162.03 2003-10-21 16:38:00       A -38.461 -18.425 0.12847222   no   1
5 20162.03 2003-10-21 18:50:00       A -38.322 -18.512 0.09166667   no   1
6 20162.03 2003-10-23 10:33:00       B -38.674 -19.824 1.65486111  gap   2
7  20162.03 2003-10-23 17:52:00       B -38.957 -19.511 0.30486111   no  2
8  20162.03 2003-11-02 08:14:00       B -42.084 -24.071 9.59861111  gap  3
9  20162.03 2003-11-02 09:36:00       A -41.999 -24.114 0.05694444   no  3
10 20687.03 2003-10-27 17:02:00 Tagging -39.320 -18.460         NA <NA>  4
11 20687.03 2003-10-27 19:44:00       2 -39.306 -18.454 0.11250000   no  4
12 20687.03 2003-10-27 21:05:00       1 -39.301 -18.458 0.05625000   no  4

但是,正如你所见,我有一个“间隙”和“否”的序列,还有 NA。 我找不到解决方案。 有人有解决办法吗?

编辑:

structure(list(id = c("20162.03", "20162.03", "20162.03", "20162.03", 
"20162.03", "20162.03", "20162.03", "20162.03", "20162.03", "20687.03", 
"20687.03", "20687.03"), date = structure(c(1066573980, 1066738740, 
1066743180, 1066754280, 1066762200, 1066905180, 1066931520, 1067760840, 
1067765760, 1067274120, 1067283840, 1067288700), class = c("POSIXct", 
"POSIXt"), tzone = "GMT"), lc = structure(c(4L, 1L, 1L, 2L, 2L, 
3L, 3L, 3L, 2L, 4L, 6L, 1L), .Label = c("1", "A", "B", "Tagging", 
"0", "2", "3", "N", "P", "Z"), class = "factor"), lon = c(-39.37, 
-38.517, -38.464, -38.461, -38.322, -38.674, -38.957, -42.084, 
-41.999, -39.32, -39.306, -39.301), lat = c(-18.48, -18.253, 
-18.302, -18.425, -18.512, -19.824, -19.511, -24.071, -24.114, 
-18.46, -18.454, -18.458), gap_days = c(NA, 1.90694444444444, 
0.0513888888888889, 0.128472222222222, 0.0916666666666667, 1.65486111111111, 
0.304861111111111, 9.59861111111111, 0.0569444444444444, NA, 
0.1125, 0.05625), gap = c(NA, "gap", "no", "no", "no", "gap", 
"no", "gap", "no", NA, "no", "no")), row.names = c(NA, 12L), class = "data.frame")

【问题讨论】:

标签: r dataframe split sequence


【解决方案1】:

使用 Base R 的简单解决方案:

df$seq <- ave(sapply(df$gap, identical, "gap"), df$id, FUN = cumsum)
df
#>          id                date      lc     lon     lat   gap_days  gap seq
#> 1  20162.03 2003-10-19 14:33:00 Tagging -39.370 -18.480         NA <NA>   0
#> 2  20162.03 2003-10-21 12:19:00       1 -38.517 -18.253 1.90694444  gap   1
#> 3  20162.03 2003-10-21 13:33:00       1 -38.464 -18.302 0.05138889   no   1
#> 4  20162.03 2003-10-21 16:38:00       A -38.461 -18.425 0.12847222   no   1
#> 5  20162.03 2003-10-21 18:50:00       A -38.322 -18.512 0.09166667   no   1
#> 6  20162.03 2003-10-23 10:33:00       B -38.674 -19.824 1.65486111  gap   2
#> 7  20162.03 2003-10-23 17:52:00       B -38.957 -19.511 0.30486111   no   2
#> 8  20162.03 2003-11-02 08:14:00       B -42.084 -24.071 9.59861111  gap   3
#> 9  20162.03 2003-11-02 09:36:00       A -41.999 -24.114 0.05694444   no   3
#> 10 20687.03 2003-10-27 17:02:00 Tagging -39.320 -18.460         NA <NA>   0
#> 11 20687.03 2003-10-27 19:44:00       2 -39.306 -18.454 0.11250000   no   0
#> 12 20687.03 2003-10-27 21:05:00       1 -39.301 -18.458 0.05625000   no   0

然后拆分:

split(df, list(df$id, df$seq), drop = TRUE)
#> $`20162.03.0`
#>         id                date      lc    lon    lat gap_days  gap seq
#> 1 20162.03 2003-10-19 14:33:00 Tagging -39.37 -18.48       NA <NA>   0
#> 
#> $`20687.03.0`
#>          id                date      lc     lon     lat gap_days  gap seq
#> 10 20687.03 2003-10-27 17:02:00 Tagging -39.320 -18.460       NA <NA>   0
#> 11 20687.03 2003-10-27 19:44:00       2 -39.306 -18.454  0.11250   no   0
#> 12 20687.03 2003-10-27 21:05:00       1 -39.301 -18.458  0.05625   no   0
#> 
#> $`20162.03.1`
#>         id                date lc     lon     lat   gap_days gap seq
#> 2 20162.03 2003-10-21 12:19:00  1 -38.517 -18.253 1.90694444 gap   1
#> 3 20162.03 2003-10-21 13:33:00  1 -38.464 -18.302 0.05138889  no   1
#> 4 20162.03 2003-10-21 16:38:00  A -38.461 -18.425 0.12847222  no   1
#> 5 20162.03 2003-10-21 18:50:00  A -38.322 -18.512 0.09166667  no   1
#> 
#> $`20162.03.2`
#>         id                date lc     lon     lat  gap_days gap seq
#> 6 20162.03 2003-10-23 10:33:00  B -38.674 -19.824 1.6548611 gap   2
#> 7 20162.03 2003-10-23 17:52:00  B -38.957 -19.511 0.3048611  no   2
#> 
#> $`20162.03.3`
#>         id                date lc     lon     lat   gap_days gap seq
#> 8 20162.03 2003-11-02 08:14:00  B -42.084 -24.071 9.59861111 gap   3
#> 9 20162.03 2003-11-02 09:36:00  A -41.999 -24.114 0.05694444  no   3

【讨论】:

  • 嗨,@Edo。感谢您的消息,但我仍然有 NA 的问题。
  • 您想如何处理 NA?
  • 我试过 df %&gt;% group_split(gap) 但显示我有 NA 的消息
  • @Anne,间隙列中的 NA 应该是“否”?看起来您在每个 id 序列的开头都有 NA(如果您从 date 计算 gap_days 是有道理的)。我认为我在编辑中所做的拆分正是您想要的。
  • 是的,但在您的示例中,第二行在第一行之后超过 1 天。根据您自己的规则,这意味着第一行和第二行必须在两个不同的组中。第二个ID的第一行和第二行是不一样的,确实是同一个组,因为他们比一天更接近。
猜你喜欢
  • 2012-04-26
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 2022-12-12
  • 2012-08-13
  • 2020-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多