使用 R,如何使用 dplyr 的超前和滞后函数从 POSIXct 变量中正确减去一秒?

Using R, how can I correctly subtract a second from a POSIXct variable using dplyr's lead and lag functions?

我在 POSIXct 格式的 table 中有 12 个日期和时间:

                Time
1  2017-03-11 01:10:09
2  2017-03-11 03:07:58
3  2017-03-12 19:16:47
4  2017-03-13 09:52:04
5  2017-03-17 20:36:35
6  2017-03-18 03:10:54
7  2017-03-18 07:29:31
8  2017-03-18 10:13:37
9  2017-03-20 10:19:31
10 2017-03-20 12:11:39
11 2017-03-20 12:11:39
12 2017-03-20 14:16:12

如果一个条目与以下条目匹配,我想从时间中删除一秒钟。例如,第 10 行应显示为“2017-03-20 12:11:38”。

我正在尝试执行类似以下操作但有效:

df %>% mutate(Time = ifelse(Time == lead(Time), Time-1, Time))

我们可以使用 case_when 而不是 ifelse 并且使用 case_when 我们也可以有多个条件而不是使用嵌套的 ifelseif_else

library(dplyr)
library(lubridate)
df %>%
   mutate(Time = as.POSIXct(Time), 
          Time = case_when(Time == lead(Time) ~ 
                   Time - seconds(1), TRUE ~ Time))

-输出

#          Time
#1  2017-03-11 01:10:09
#2  2017-03-11 03:07:58
#3  2017-03-12 19:16:47
#4  2017-03-13 09:52:04
#5  2017-03-17 20:36:35
#6  2017-03-18 03:10:54
#7  2017-03-18 07:29:31
#8  2017-03-18 10:13:37
#9  2017-03-20 10:19:31
#10 2017-03-20 12:11:38
#11 2017-03-20 12:11:39
#12 2017-03-20 14:16:12

或者使用base R,我们创建一个逻辑索引并赋值

i1 <- c(df$Time[-1]  == df$Time[-nrow(df)], FALSE)
df$Time <- as.POSIXct(df$Time)
df$Time[i1] <- df$Time[i1] - 1

数据

df <- structure(list(Time = c("2017-03-11 01:10:09", "2017-03-11 03:07:58", 
"2017-03-12 19:16:47", "2017-03-13 09:52:04", "2017-03-17 20:36:35", 
"2017-03-18 03:10:54", "2017-03-18 07:29:31", "2017-03-18 10:13:37", 
"2017-03-20 10:19:31", "2017-03-20 12:11:39", "2017-03-20 12:11:39", 
"2017-03-20 14:16:12")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))

您的方法是正确的,但是,base::ifelse 剥离了使 POSIXct 列为数字的属性。为避免这种情况,因为您正在使用 dplyr 您可以使用 dplyr::if_else 保留 class.

另请注意,lead 将为 Time 中的最后一个值生成 NA,因此比较 Time == lead(Time) 将生成 NA。我们可以在 if_else.

中将 missing 参数设置为 Time
library(dplyr)
df %>% mutate(Time = if_else(Time == lead(Time), Time-1, Time, missing = Time))

#                  Time
#1  2017-03-11 01:10:09
#2  2017-03-11 03:07:58
#3  2017-03-12 19:16:47
#4  2017-03-13 09:52:04
#5  2017-03-17 20:36:35
#6  2017-03-18 03:10:54
#7  2017-03-18 07:29:31
#8  2017-03-18 10:13:37
#9  2017-03-20 10:19:31
#10 2017-03-20 12:11:38
#11 2017-03-20 12:11:39
#12 2017-03-20 14:16:12