R如何按组滞后数据帧

时间:2018-12-07 01:22:15

标签: r dplyr

我有以下数据集:

       RecordedAtTime VehicleRef          timeDelta
0 2017-08-23 10:01:19  NYCT_1202                NaT <-Should be 00:10:29
1 2017-08-23 10:11:48  NYCT_1202    0 days 00:10:29 <-Should be 02:39:43

2 2017-08-23 12:51:31  NYCT_1202    0 days 02:39:43
3 2017-08-23 13:02:02  NYCT_1202    0 days 00:10:31
4 2017-08-23 13:11:27  NYCT_1202    0 days 00:09:25
5 2017-08-23 13:51:35  NYCT_1202    0 days 00:40:08 <-Should be 02:20:52

6 2017-08-23 16:12:27  NYCT_1202    0 days 02:20:52
7 2017-08-23 16:52:25  NYCT_1202    0 days 00:39:58 <-Should be +16:41:17

8 2017-08-07 09:33:42  NYCT_1206 -17 days +16:41:17
9 2017-08-07 10:13:36  NYCT_1206    0 days 00:39:54 <-Should be next difference

我想按以下分组添加滞后变量:名称,VarA,VarB,以便我的数据看起来像:

.diff

我找到了以下链接,这对您很有帮助:TimeSpan

并且正在使用以下代码:

Name  Year  VarA  VarB Data.1  Data.2
A     2016  L     H    100     101
A     2017  L     H    105     99
A     2018  L     H    103     105
A     2016  L     A    90      95
A     2017  L     A    99      92
A     2018  L     A    102     101

但是,滞后性抵消了所有与名称相关的数据,而不是我想要的分组,因此只有2018年被准确地滞后了。

Name  Year  VarA  VarB Data.1  Data.2  Lg1.Data.1 Lg2.Data.1
A     2016  L     H    100     101     NA        NA
A     2017  L     H    105     99      100       NA
A     2018  L     H    103     105     105       100
A     2016  L     A    90      95      NA        NA
A     2017  L     A    99      92      90        NA
A     2018  L     A    102     101     99        90

如何为每个新的分组组合(例如名称/ VarA / VarB)重置滞后时间?

1 个答案:

答案 0 :(得分:1)

dplyr::lag使您可以设置要滞后的距离。在制作滞后变量之前,您可以按所需的任意变量分组(在这种情况下为NameVarAVarB

library(dplyr)

df %>%
  group_by(Name, VarA, VarB) %>%
  mutate(Lg1.Data.1 = lag(Data.1, n = 1), Lg2.Data.1 = lag(Data.1, n = 2))
#> # A tibble: 6 x 8
#> # Groups:   Name, VarA, VarB [2]
#>   Name   Year VarA  VarB  Data.1 Data.2 Lg1.Data.1 Lg2.Data.1
#>   <chr> <dbl> <chr> <chr>  <dbl>  <dbl>      <dbl>      <dbl>
#> 1 A      2016 L     H        100    101         NA         NA
#> 2 A      2017 L     H        105     99        100         NA
#> 3 A      2018 L     H        103    105        105        100
#> 4 A      2016 L     A         90     95         NA         NA
#> 5 A      2017 L     A         99     92         90         NA
#> 6 A      2018 L     A        102    101         99         90

如果要扩展到更大的滞后,可以使用一些non-standard evaluation动态创建新的滞后列。我将使用purrr::map进行此操作,以迭代要滞后的n集合,列出添加了新列的数据帧列表,然后将所有数据帧连接在一起。 NSE可能有更好的方法来执行此操作,因此希望有人可以对此进行改进。

我正在整理一些新数据,以期进行更广泛的说明。在mutate内,您可以使用quo_name创建列名。

library(dplyr)
library(purrr)

set.seed(127)
df <- tibble(
  Name = "A", Year = rep(2016:2020, 2), VarA = "L", VarB = rep(c("H", "A"), each = 5),
  Data.1 = sample(1:10, 10, replace = T), Data.2 = sample(1:10, 10, replace = T) 
)

df_list <- purrr::map(1:4, function(i) {
  df %>%
    group_by(Name, VarA, VarB) %>%
    mutate(!!quo_name(paste0("Lag", i)) := dplyr::lag(Data.1, n = i))
})

您不需要保存此列表-我只是在做它以显示数据帧之一的示例。您可以直接进入reduce

df_list[[3]]
#> # A tibble: 10 x 7
#> # Groups:   Name, VarA, VarB [2]
#>    Name   Year VarA  VarB  Data.1 Data.2  Lag3
#>    <chr> <int> <chr> <chr>  <int>  <int> <int>
#>  1 A      2016 L     H          3      9    NA
#>  2 A      2017 L     H          1      4    NA
#>  3 A      2018 L     H          3      8    NA
#>  4 A      2019 L     H          2      2     3
#>  5 A      2020 L     H          4      5     1
#>  6 A      2016 L     A          8      4    NA
#>  7 A      2017 L     A          6      8    NA
#>  8 A      2018 L     A          3      2    NA
#>  9 A      2019 L     A          8      6     8
#> 10 A      2020 L     A          9      1     6

然后使用purrr::reduce联接列表中的所有数据框。由于每个数据帧中都有相同的列,而这些列是您要加入的列,因此您可以不用在inner_join中指定加入列。

reduce(df_list, inner_join)
#> Joining, by = c("Name", "Year", "VarA", "VarB", "Data.1", "Data.2")
#> Joining, by = c("Name", "Year", "VarA", "VarB", "Data.1", "Data.2")
#> Joining, by = c("Name", "Year", "VarA", "VarB", "Data.1", "Data.2")
#> # A tibble: 10 x 10
#> # Groups:   Name, VarA, VarB [?]
#>    Name   Year VarA  VarB  Data.1 Data.2  Lag1  Lag2  Lag3  Lag4
#>    <chr> <int> <chr> <chr>  <int>  <int> <int> <int> <int> <int>
#>  1 A      2016 L     H          3      9    NA    NA    NA    NA
#>  2 A      2017 L     H          1      4     3    NA    NA    NA
#>  3 A      2018 L     H          3      8     1     3    NA    NA
#>  4 A      2019 L     H          2      2     3     1     3    NA
#>  5 A      2020 L     H          4      5     2     3     1     3
#>  6 A      2016 L     A          8      4    NA    NA    NA    NA
#>  7 A      2017 L     A          6      8     8    NA    NA    NA
#>  8 A      2018 L     A          3      2     6     8    NA    NA
#>  9 A      2019 L     A          8      6     3     6     8    NA
#> 10 A      2020 L     A          9      1     8     3     6     8

reprex package(v0.2.1)于2018-12-07创建