[英]Identify top n observations and aggregate by year all variables in dataframe R
在下面的 dataframe 中,我想每年通過“id”和最高變量“op”來識別兩個觀察值。 然后匯總變量 op、tr、cp 的兩個最高觀察值。 我將不勝感激 dplyr 的回答。我原來的 dataframe 有成千上萬的觀察結果,所以如果我想要 select 每年 1000 個最高的“op”觀察結果,我需要一些我可以調整的東西。
數據:
year id op tr cp
1 1984 1 10 10 10
2 1985 1 20 20 20
3 1986 1 30 30 30
4 1987 1 40 40 40
5 1988 1 50 50 50
6 1985 2 15 15 15
7 1986 2 17 17 17
8 1987 2 18 18 18
9 1988 2 19 19 19
10 1985 3 20 20 20
11 1986 3 22 22 22
12 1986 4 10 10 10
13 1987 4 20 20 20
14 1988 4 40 40 40
預計 output:
year2 op2 tr2 cp2
1 1984 10 10 10
2 1985 40 40 40
3 1986 52 52 52
4 1987 60 60 60
5 1988 90 90 90
所以在 1984 年 highestop 由 id=1 聚合,在第二個 id=1 和 3,在 1986 年 id=1 和 3,在 1987 年 id=1 和 4,1988 年 id=1 和 4。
我想避免使用 function 但不確定是否可能。 可以使用功能良好的 function。
data <-
structure(list(year = c(1984L, 1985L, 1986L, 1987L, 1988L, 1985L,
1986L, 1987L, 1988L, 1985L, 1986L, 1986L, 1987L, 1988L),
id = c(1L,1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 4L, 4L, 4L),
op = c(10L,20L, 30L, 40L, 50L, 15L, 17L, 18L, 19L, 20L, 22L, 10L, 20L, 40L),
tr = c(10L, 20L, 30L, 40L, 50L, 15L, 17L, 18L, 19L, 20L, 22L,10L, 20L, 40L),
cp = c(10L, 20L, 30L, 40L, 50L, 15L, 17L, 18L,19L, 20L, 22L, 10L, 20L, 40L)),
class = "data.frame",row.names = c(NA,-14L))
library(dplyr)
data %>%
select(-id) %>%
group_by(year) %>%
slice_max(n = 2,order_by = op) %>%
summarise(across(.fns = ~sum(.,na.rm = TRUE)))
# A tibble: 5 x 4
year op tr cp
<int> <int> <int> <int>
1 1984 10 10 10
2 1985 40 40 40
3 1986 52 52 52
4 1987 60 60 60
5 1988 90 90 90
您可以across
列進行group_by
和reframe
/ summarise
,並按降序對值進行sort
,select 是兩個最高值(請注意:使用na.rm = TRUE
是因為您的第一組只有一個值,因此選擇兩個值一個是不適用):
library(dplyr)
df %>%
select(-id) %>%
group_by(year) %>%
reframe(across(op:cp, ~sum(sort(.x, decreasing = TRUE)[1:2], na.rm = TRUE)))
#> # A tibble: 5 × 4
#> year op tr cp
#> <int> <int> <int> <int>
#> 1 1984 10 10 10
#> 2 1985 40 40 40
#> 3 1986 52 52 52
#> 4 1987 60 60 60
#> 5 1988 90 90 90
創建於 2023-01-14,使用reprex v2.0.2
reframe
和summarise
之間的一個區別是 reframe 返回未分組的 dataframe。
您也可以像這樣使用summarise
:
library(dplyr)
df %>%
group_by(year) %>%
summarise(across(op:cp, ~sum(sort(.x, decreasing = TRUE)[1:2], na.rm = TRUE)))
使用data.table
library(data.table)
setDT(df1)[, lapply(.SD, \(x) sum(head(x[order(-x)],2), na.rm = TRUE)),
year, .SDcols = op:cp]
-輸出
year op tr cp
1: 1984 10 10 10
2: 1985 40 40 40
3: 1986 52 52 52
4: 1987 60 60 60
5: 1988 90 90 90
請嘗試以下代碼
library(dplyr)
data2 <- data_a %>% dplyr::arrange(year,desc(op),id) %>% group_by(year) %>%
slice_head(n=2) %>% mutate(across(c('op','tr','cp'), ~ sum(.x), .names = '{col}2')) %>% slice_head(n=1) %>%
select(-id,-op,-tr,-cp)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.