使用 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
我们也可以有多个条件而不是使用嵌套的 ifelse
或 if_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
我在 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
我们也可以有多个条件而不是使用嵌套的 ifelse
或 if_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