我正在嘗試匯總資料框,同時按變數分組。我的問題是,在執行這樣的匯總程序時,我丟失了我需要的其他列。
考慮以下資料:
df <-
tibble::tribble(
~id, ~year, ~my_value,
1, 2010, 2,
1, 2013, 2,
1, 2014, 2,
2, 2010, 4,
2, 2012, 3,
2, 2014, 4,
2, 2015, 2,
3, 2015, 3,
3, 2010, 3,
3, 2011, 3
)
我想分組id以折疊my_value為單個值。我使用以下演算法:
- 如果 的所有值
my_value都相同,則簡單地回傳第一個值,即my_value[1]。 - ELSE 回傳最小值,即
min(my_value)。
所以我寫了一個小函式來做到這一點:
my_func <- function(x) {
if (var(x) == 0) {
return(x[1])
}
# else:
min(x)
}
現在我可以使用dplyr或data.table來總結id:
library(dplyr)
library(data.table)
# dplyr
df %>%
group_by(id) %>%
summarise(my_min_val = my_func(my_value))
#> # A tibble: 3 x 2
#> id my_min_val
#> <dbl> <dbl>
#> 1 1 2
#> 2 2 2
#> 3 3 3
# data.table
setDT(df)[, .(my_min_val = my_func(my_value)), by = "id"]
#> id my_min_val
#> 1: 1 2
#> 2: 2 2
#> 3: 3 3
到現在為止還挺好。我的問題是我失去了year價值。我想要year每個所選my_value.
我想要的輸出應該是這樣的:
# desired output
desired_output <-
tribble(~id, ~my_min_val, ~year,
1, 2, 2010, # because for id 1, var(my_value) is 0, and hence my_value[1] corresponds to year 2010
2, 2, 2015, # because for id 2, var(my_value) is not 0, and hence min(my_value) (which is 2) corresponds to year 2015
3, 3, 2015) # because for id 3, var(my_value) is 0, hence my_value[1] corresponds to year 2015
我特別尋求data.table解決方案,因為我的真實資料非常大(超過 100 萬行)并且有很多組。因此,效率很重要。謝謝!
uj5u.com熱心網友回復:
我們可以使用條件 slice
library(dplyr)
my_func <- function(x) if(var(x) == 0) 1 else which.min(x)
df %>%
group_by(id) %>%
slice(my_func(my_value)) %>%
ungroup
-輸出
# A tibble: 3 × 3
id year my_value
<dbl> <dbl> <dbl>
1 1 2010 2
2 2 2015 2
3 3 2015 3
或使用 data.table
library(data.table)
setDT(df)[df[, .I[my_func(my_value)], id]$V1]
id year my_value
1: 1 2010 2
2: 2 2015 2
3: 3 2015 3
或slice_min與with_ties = FALSE
df %>%
group_by(id) %>%
slice_min(n = 1, order_by = my_value, with_ties = FALSE) %>%
ungroup
-輸出
# A tibble: 3 × 3
id year my_value
<dbl> <dbl> <dbl>
1 1 2010 2
2 2 2015 2
3 3 2015 3
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/375175.html
上一篇:mapply不顯示變數名稱
