我有以下数据集:
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)重置滞后时间?
答案 0 :(得分:1)
dplyr::lag
使您可以设置要滞后的距离。在制作滞后变量之前,您可以按所需的任意变量分组(在这种情况下为Name
,VarA
和VarB
。
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创建