根据前一行 (R) 的值删除数据框中的一行
Removing a row in a data frame depending on the value of the previous row (R)
我试图在将一些数据作为数据框导入 R 后对其进行清理。
我的数据如下所示:
Event Time
A 10:59:36
B 11:00:27
A 11:01:36
B 11:02:01
A 11:02:15
A 11:02:20
B 11:02:45
时间在 POSIXct 对象中。事件是字符串。
数据的正确形式应该是:
A 之后是 B。
但是,有时 A 后面跟着 A,B 后面跟着 B。这是一个错误,我需要删除后一行。
因此,如果后续两行的 'Event' 值相同,则必须删除第二行。
任何帮助将不胜感激。
您可以使用cumsum()
和rle()
函数来实现您想要的:
events <- data.frame(Event=c("A", "B", "A", "B", "A", "A", "B"),
Time=c("10:59:36", "11:00:27", "11:01:36",
"11:02:01", "11:02:15", "11:02:20", "11:02:45"))
rows.keep <- cumsum(rle(as.numeric(events[,1]))$lengths)
y <- c(FALSE, rows.keep[1:length(rows.keep)-1] == rows.keep[2:length(rows.keep)] - 2)
rows.keep[y] <- rows.keep[y] - 1
events <- events[rows.keep, ]
> events
Event Time
1 A 2016-01-25 10:59:36
2 B 2016-01-25 11:00:27
3 A 2016-01-25 11:01:36
4 B 2016-01-25 11:02:01
5 A 2016-01-25 11:02:15
6 B 2016-01-25 11:02:45
我们可以用 data.table
中的 rleid
来做到这一点
library(data.table)
setDT(df1)[!duplicated(rleid(Event))]
# Event Time
#1: A 10:59:36
#2: B 11:00:27
#3: A 11:01:36
#4: B 11:02:01
#5: A 11:02:15
#6: B 11:02:45
数据
df1 <- structure(list(Event = c("A", "B", "A", "B", "A",
"A", "B"),
Time = c("10:59:36", "11:00:27", "11:01:36", "11:02:01",
"11:02:15", "11:02:20", "11:02:45")), .Names = c("Event",
"Time"), class = "data.frame", row.names = c(NA, -7L))
一个dplyr
解决方案。 row_number
条件对我来说有点笨拙,但它可能比其他解决方案更具可读性。
library(dplyr)
Time <- as.POSIXct("2016-01-25 10:59:36")
set.seed(10)
dat <-
data_frame(Event = sample(c("A", "B"), size = 15, replace = TRUE)) %>%
mutate(Time = Sys.time() + rnorm(15, 0, 999)) %>%
arrange(Time)
dat %>%
arrange(Time) %>%
filter(Event != lag(Event) | row_number(Time) == 1)
# Source: local data frame [9 x 2]
#
# Event Time
# (chr) (time)
# 1 B 2016-01-25 18:36:16
# 2 A 2016-01-25 18:46:30
# 3 B 2016-01-25 18:55:18
# 4 A 2016-01-25 18:58:18
# 5 B 2016-01-25 19:03:10
# 6 A 2016-01-25 19:07:20
# 7 B 2016-01-25 19:09:24
# 8 A 2016-01-25 19:14:35
# 9 B 2016-01-25 19:26:27
如果没有 | row_number(Time) == 1)
,第一行将被省略。请注意,如果有多个重复的连续事件,则只保留第一个。
我试图在将一些数据作为数据框导入 R 后对其进行清理。 我的数据如下所示:
Event Time
A 10:59:36
B 11:00:27
A 11:01:36
B 11:02:01
A 11:02:15
A 11:02:20
B 11:02:45
时间在 POSIXct 对象中。事件是字符串。 数据的正确形式应该是: A 之后是 B。 但是,有时 A 后面跟着 A,B 后面跟着 B。这是一个错误,我需要删除后一行。 因此,如果后续两行的 'Event' 值相同,则必须删除第二行。 任何帮助将不胜感激。
您可以使用cumsum()
和rle()
函数来实现您想要的:
events <- data.frame(Event=c("A", "B", "A", "B", "A", "A", "B"),
Time=c("10:59:36", "11:00:27", "11:01:36",
"11:02:01", "11:02:15", "11:02:20", "11:02:45"))
rows.keep <- cumsum(rle(as.numeric(events[,1]))$lengths)
y <- c(FALSE, rows.keep[1:length(rows.keep)-1] == rows.keep[2:length(rows.keep)] - 2)
rows.keep[y] <- rows.keep[y] - 1
events <- events[rows.keep, ]
> events
Event Time
1 A 2016-01-25 10:59:36
2 B 2016-01-25 11:00:27
3 A 2016-01-25 11:01:36
4 B 2016-01-25 11:02:01
5 A 2016-01-25 11:02:15
6 B 2016-01-25 11:02:45
我们可以用 data.table
rleid
来做到这一点
library(data.table)
setDT(df1)[!duplicated(rleid(Event))]
# Event Time
#1: A 10:59:36
#2: B 11:00:27
#3: A 11:01:36
#4: B 11:02:01
#5: A 11:02:15
#6: B 11:02:45
数据
df1 <- structure(list(Event = c("A", "B", "A", "B", "A",
"A", "B"),
Time = c("10:59:36", "11:00:27", "11:01:36", "11:02:01",
"11:02:15", "11:02:20", "11:02:45")), .Names = c("Event",
"Time"), class = "data.frame", row.names = c(NA, -7L))
一个dplyr
解决方案。 row_number
条件对我来说有点笨拙,但它可能比其他解决方案更具可读性。
library(dplyr)
Time <- as.POSIXct("2016-01-25 10:59:36")
set.seed(10)
dat <-
data_frame(Event = sample(c("A", "B"), size = 15, replace = TRUE)) %>%
mutate(Time = Sys.time() + rnorm(15, 0, 999)) %>%
arrange(Time)
dat %>%
arrange(Time) %>%
filter(Event != lag(Event) | row_number(Time) == 1)
# Source: local data frame [9 x 2]
#
# Event Time
# (chr) (time)
# 1 B 2016-01-25 18:36:16
# 2 A 2016-01-25 18:46:30
# 3 B 2016-01-25 18:55:18
# 4 A 2016-01-25 18:58:18
# 5 B 2016-01-25 19:03:10
# 6 A 2016-01-25 19:07:20
# 7 B 2016-01-25 19:09:24
# 8 A 2016-01-25 19:14:35
# 9 B 2016-01-25 19:26:27
如果没有 | row_number(Time) == 1)
,第一行将被省略。请注意,如果有多个重复的连续事件,则只保留第一个。