我有一個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
應答器指示個人和單位的位置。我想通過洗掉重復的行來創建該資料集的更稀疏版本,但僅洗掉那些連續的行。本質上,因為連續的重復只是意味著沒有運動。這意味著我希望我的最終結果是:
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條目。(我在日期、轉發器和單位的子集上重復運行):
> 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
關于如何“優雅地”解決這個問題的任何想法,即不必遍歷這個?
uj5u.com熱心網友回復:
使用rleidfromdata.table我們創建一個虛擬分組變數,并使用distinctfromdplyr我們洗掉重復項。在您的資料中,您可能希望包含Transponder在rleid函式中,如果它在您的真實資料中確實有所不同。
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)),],基于評論。
uj5u.com熱心網友回復:
請參閱過濾掉 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
uj5u.com熱心網友回復:
我想嘗試一下 using 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,但如果您的資料很大,這至少應該比轉換為 adata.frame和 using更快dplyr。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/447560.html
