仅当它们直接连续复制时才删除 R 中的行
Removing rows in R only if they are duplicated in direct succession
我有一个 data.table
指示动物的位置,看起来像这样:
Date TimeStamp Transponder Units
1: 2021-08-15 2021-08-15 14:11:13 DA2C614E M2
2: 2021-08-15 2021-08-15 14:11:14 DA2C614E M2
3: 2021-08-15 2021-08-15 14:11:14 DA2C614E M2
4: 2021-08-15 2021-08-15 14:11:15 DA2C614E M2
5: 2021-08-15 2021-08-15 14:11:15 DA2C614E M2
6: 2021-08-15 2021-08-15 14:11:16 DA2C614E M2
7: 2021-08-15 2021-08-15 14:12:40 DA2C614E HM2
8: 2021-08-15 2021-08-15 14:12:40 DA2C614E HM2
9: 2021-08-15 2021-08-15 14:12:49 DA2C614E H2
10: 2021-08-15 2021-08-15 14:18:02 DA2C614E H1
11: 2021-08-15 2021-08-15 14:18:04 DA2C614E H1
12: 2021-08-15 2021-08-15 14:19:19 DA2C614E H1
13: 2021-08-15 2021-08-15 14:25:29 DA2C614E HM2
T运行sponder表示个人和Units的位置。我想通过删除重复的行来创建此数据集的更稀疏版本,但 仅 那些连续的行。本质上,因为连续的重复只是意味着没有移动。这意味着我希望我的最终结果是:
Date TimeStamp Transponder Units
1: 2021-08-15 2021-08-15 14:11:13 DA2C614E M2
2: 2021-08-15 2021-08-15 14:12:40 DA2C614E HM2
3: 2021-08-15 2021-08-15 14:12:49 DA2C614E H2
4: 2021-08-15 2021-08-15 14:18:02 DA2C614E H1
5: 2021-08-15 2021-08-15 14:25:29 DA2C614E HM2
我曾尝试使用 duplicated()
,但问题是此函数会删除 所有 重复项,例如后来重复的 HM2
条目。 (我 运行 在 Date、T运行sponder 和 Units 的子集上复制):
> sample[!duplicated(sample[, c(1,3,4)]),]
Date TimeStamp Transponder Units
1: 2021-08-15 2021-08-15 14:11:13 DA2C614E M2
2: 2021-08-15 2021-08-15 14:12:40 DA2C614E HM2
3: 2021-08-15 2021-08-15 14:12:49 DA2C614E H2
4: 2021-08-15 2021-08-15 14:18:02 DA2C614E H1
关于如何“优雅地”解决这个问题,即无需循环解决这个问题,有什么想法吗?
见Filtering out duplicated/non-unique rows in data.table
我认为如果您的数据是 时间索引,这将适用于您的代码:
unique(sample, by = "Date")
示例:
dt <- data.table(V1 = LETTERS[c(1,1,1,2,2,2)], V2 = c(1,1,1,2,2,2))
V1 V2
1: A 1
2: A 1
3: A 1
4: B 2
5: B 2
6: B 2
unique(dt, by = "V1")
V1 V2
1: A 1
2: B 2
我们使用 data.table
中的 rleid
创建一个 dummy-grouping 变量,并使用 dplyr
中的 distinct
删除重复项。在您的数据中,您可能希望在 rleid
函数中包含 Transponder
,如果它在您的真实数据中确实有所不同。
library(tidyverse)
library(data.table)
df %>%
mutate(dummy = rleid(Units)) %>%
distinct(dummy, .keep_all = T) %>%
select(-dummy)
Date TimeStamp Transponder Units
1 2021-08-15 2021-08-15-14:11:13 DA2C614E M2
2 2021-08-15 2021-08-15-14:12:40 DA2C614E HM2
3 2021-08-15 2021-08-15-14:12:49 DA2C614E H2
4 2021-08-15 2021-08-15-14:18:02 DA2C614E H1
5 2021-08-15 2021-08-15-14:25:29 DA2C614E HM2
仅使用 data.table
而没有临时变量,您可以执行以下操作:dt[!duplicated(rleid(Units)),]
,基于评论。
我想尝试使用 data.table
,正如您所说,您正在使用它,大概是因为您的数据很大,所以这应该比建议的 dplyr
方法更快。我对 data.table
没有太多经验,所以我想尝试一下,这似乎有效:
# Cols to subset
cols <- c("Date", "Transponder", "Units")
lagcols <- paste0(cols, "_lag")
# Create lag
sample[, (lagcols) := shift(.SD, n = 1, fill = NA, type = "lag"), .SDcols = cols]
# Create boolean mask if row == previous row in selected columns
sample[, equals_previous := Date == Date_lag & Transponder == Transponder_lag & Units == Units_lag]
# Delete lag columns
sample[, (lagcols) := NULL]
# Subset only rows where they are not equal to the previous row
sample[(!equals_previous)]
在 data.table
中可能有更优雅的方法来执行此操作,但如果您的数据量很大,这至少应该比转换为 data.frame
并使用 [=12] 更快=].
我有一个 data.table
指示动物的位置,看起来像这样:
Date TimeStamp Transponder Units
1: 2021-08-15 2021-08-15 14:11:13 DA2C614E M2
2: 2021-08-15 2021-08-15 14:11:14 DA2C614E M2
3: 2021-08-15 2021-08-15 14:11:14 DA2C614E M2
4: 2021-08-15 2021-08-15 14:11:15 DA2C614E M2
5: 2021-08-15 2021-08-15 14:11:15 DA2C614E M2
6: 2021-08-15 2021-08-15 14:11:16 DA2C614E M2
7: 2021-08-15 2021-08-15 14:12:40 DA2C614E HM2
8: 2021-08-15 2021-08-15 14:12:40 DA2C614E HM2
9: 2021-08-15 2021-08-15 14:12:49 DA2C614E H2
10: 2021-08-15 2021-08-15 14:18:02 DA2C614E H1
11: 2021-08-15 2021-08-15 14:18:04 DA2C614E H1
12: 2021-08-15 2021-08-15 14:19:19 DA2C614E H1
13: 2021-08-15 2021-08-15 14:25:29 DA2C614E HM2
T运行sponder表示个人和Units的位置。我想通过删除重复的行来创建此数据集的更稀疏版本,但 仅 那些连续的行。本质上,因为连续的重复只是意味着没有移动。这意味着我希望我的最终结果是:
Date TimeStamp Transponder Units
1: 2021-08-15 2021-08-15 14:11:13 DA2C614E M2
2: 2021-08-15 2021-08-15 14:12:40 DA2C614E HM2
3: 2021-08-15 2021-08-15 14:12:49 DA2C614E H2
4: 2021-08-15 2021-08-15 14:18:02 DA2C614E H1
5: 2021-08-15 2021-08-15 14:25:29 DA2C614E HM2
我曾尝试使用 duplicated()
,但问题是此函数会删除 所有 重复项,例如后来重复的 HM2
条目。 (我 运行 在 Date、T运行sponder 和 Units 的子集上复制):
> sample[!duplicated(sample[, c(1,3,4)]),]
Date TimeStamp Transponder Units
1: 2021-08-15 2021-08-15 14:11:13 DA2C614E M2
2: 2021-08-15 2021-08-15 14:12:40 DA2C614E HM2
3: 2021-08-15 2021-08-15 14:12:49 DA2C614E H2
4: 2021-08-15 2021-08-15 14:18:02 DA2C614E H1
关于如何“优雅地”解决这个问题,即无需循环解决这个问题,有什么想法吗?
见Filtering out duplicated/non-unique rows in data.table
我认为如果您的数据是 时间索引,这将适用于您的代码:
unique(sample, by = "Date")
示例:
dt <- data.table(V1 = LETTERS[c(1,1,1,2,2,2)], V2 = c(1,1,1,2,2,2))
V1 V2
1: A 1
2: A 1
3: A 1
4: B 2
5: B 2
6: B 2
unique(dt, by = "V1")
V1 V2
1: A 1
2: B 2
我们使用 data.table
中的 rleid
创建一个 dummy-grouping 变量,并使用 dplyr
中的 distinct
删除重复项。在您的数据中,您可能希望在 rleid
函数中包含 Transponder
,如果它在您的真实数据中确实有所不同。
library(tidyverse)
library(data.table)
df %>%
mutate(dummy = rleid(Units)) %>%
distinct(dummy, .keep_all = T) %>%
select(-dummy)
Date TimeStamp Transponder Units
1 2021-08-15 2021-08-15-14:11:13 DA2C614E M2
2 2021-08-15 2021-08-15-14:12:40 DA2C614E HM2
3 2021-08-15 2021-08-15-14:12:49 DA2C614E H2
4 2021-08-15 2021-08-15-14:18:02 DA2C614E H1
5 2021-08-15 2021-08-15-14:25:29 DA2C614E HM2
仅使用 data.table
而没有临时变量,您可以执行以下操作:dt[!duplicated(rleid(Units)),]
,基于评论。
我想尝试使用 data.table
,正如您所说,您正在使用它,大概是因为您的数据很大,所以这应该比建议的 dplyr
方法更快。我对 data.table
没有太多经验,所以我想尝试一下,这似乎有效:
# Cols to subset
cols <- c("Date", "Transponder", "Units")
lagcols <- paste0(cols, "_lag")
# Create lag
sample[, (lagcols) := shift(.SD, n = 1, fill = NA, type = "lag"), .SDcols = cols]
# Create boolean mask if row == previous row in selected columns
sample[, equals_previous := Date == Date_lag & Transponder == Transponder_lag & Units == Units_lag]
# Delete lag columns
sample[, (lagcols) := NULL]
# Subset only rows where they are not equal to the previous row
sample[(!equals_previous)]
在 data.table
中可能有更优雅的方法来执行此操作,但如果您的数据量很大,这至少应该比转换为 data.frame
并使用 [=12] 更快=].