我有一個大型的魚檢測資料集(約 300,000 行)。每個檢測都有一個日期、一個站點(位置)和一個 tagID,以及許多其他變數,例如溫度、深度等。我想在每次魚訪問該站點時提取每個站點的第一個和最后一個檢測。最終目標是在每個站點移動之前計算每個站點的駐留時間,并在它回傳時再次計算駐留時間。
這是資料的一個小例子
tagID <- c("8272", "8272", "8272", "8272", "8272", "8272", "8272", "8272", "8272", "8272")
date <- c("2020-07-12", "2020-07-12", "2020-07-13", "2020-07-13", "2020-07-16", "2020-07-17", "2020-07-20", "2020-07-29", "2020-07-30", "2020-08-04")
station <- c("4", "4", "4", "5", "5", "6", "6", "6", "4", "4")
temp <- c("10", "9", "11", "12", "10", "12", "11", "12", "12", "9")
depth <- c("6.14", "34.2", "21", "23.5", "15.4", "54", "32.4", "23", "33.3", "32.7")
df <- data.frame(tagID, date, station, temp, depth)
資料框看起來像:
tagID date station temp depth
1 8272 2020-07-12 4 10 6.14
2 8272 2020-07-12 4 9 34.2
3 8272 2020-07-13 4 11 21
4 8272 2020-07-13 5 12 23.5
5 8272 2020-07-16 5 10 15.4
6 8272 2020-07-17 6 12 54
7 8272 2020-07-20 6 11 32.4
8 8272 2020-07-29 6 12 23
9 8272 2020-07-30 4 12 33.3
10 8272 2020-08-04 4 9 32.7
我想找到一種有效的方法來遍歷所有 300K 行并提取如下內容:
tagID date station temp depth
1 8272 2020-07-12 4 10 6.14
3 8272 2020-07-13 4 11 21
4 8272 2020-07-13 5 12 23.5
5 8272 2020-07-16 5 10 15.4
6 8272 2020-07-17 6 12 54
8 8272 2020-07-29 6 12 23
9 8272 2020-07-30 4 12 33.3
10 8272 2020-08-04 4 9 32.7
這顯示了魚在第 4 站時的第一次和最后一次檢測,然后當魚在本季晚些時候回到第 4 站時再次進行第一次和最后一次檢測。
我查看了諸如Select first and last row from grouped data和Select the first and last row by group in a data frame之類的問題,以及其他類似的問題,但這些問題都沒有考慮到第二個(第 3、第 4、第 .. .time)組(在我的例子中:站)出現在資料中。
如果您能提供幫助,請告訴我。謝謝你。(這是我關于堆疊溢位的第一個問題,對未來問題的任何提示都是有幫助的)
uj5u.com熱心網友回復:
我在這里的方法是標記魚更改站點的每個場合,然后計算這些更改的累積次數。然后我們可以按魚和站點更改數進行分組,并過濾??每個的第一個和最后一個。
library(dplyr)
df %>%
group_by(tagID) %>%
mutate(station_chg = station != lag(station, default = ""),
station_cuml = cumsum(station_chg)) %>%
group_by(tagID, station_cuml) %>%
slice(1, n()) %>%
ungroup()
結果
# A tibble: 8 x 7
tagID date station temp depth station_chg station_cuml
<chr> <chr> <chr> <chr> <chr> <lgl> <int>
1 8272 2020-07-12 4 10 6.14 TRUE 1
2 8272 2020-07-13 4 11 21 FALSE 1
3 8272 2020-07-13 5 12 23.5 TRUE 2
4 8272 2020-07-16 5 10 15.4 FALSE 2
5 8272 2020-07-17 6 12 54 TRUE 3
6 8272 2020-07-29 6 12 23 FALSE 3
7 8272 2020-07-30 4 12 33.3 TRUE 4
8 8272 2020-08-04 4 9 32.7 FALSE 4
uj5u.com熱心網友回復:
這是一種data.table方法。正如@Henrik 在評論中提到的,您可以使用rleid創建一個新列進行分組,而不是station用作station重復值。rleid. 然后,對于每個組,它將包括第一個和最后一個.N值。請注意,unique添加它是為了考慮給定組可能僅存在一行資料的情況。我希望這可能是您的快速解決方案。
library(data.table)
setDT(df)
df[ , id := rleid(station)][ , .SD[unique(c(1, .N))], by = id]
輸出
id tagID date station temp depth
1: 1 8272 2020-07-12 4 10 6.14
2: 1 8272 2020-07-13 4 11 21
3: 2 8272 2020-07-13 5 12 23.5
4: 2 8272 2020-07-16 5 10 15.4
5: 3 8272 2020-07-17 6 12 54
6: 3 8272 2020-07-29 6 12 23
7: 4 8272 2020-07-30 4 12 33.3
8: 4 8272 2020-08-04 4 9 32.7
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/417410.html
標籤:
上一篇:如果字母'a'和'b'正好相隔3個位置,我如何回傳true值?
下一篇:在一行上列印骰子
