簡體   English   中英

確定前 n 個觀察值並按年份匯總 dataframe R 中的所有變量

[英]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)))

Output

# 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_byreframe / 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

reframesummarise之間的一個區別是 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM