识别前n个观测值,并按年汇总 Dataframe R中的所有变量

fkvaft9z  于 2023-01-15  发布在  其他
关注(0)|答案(4)|浏览(101)

在下面的 Dataframe 中,我想通过"id"和最高变量"op"来确定每年的两个观测值。然后聚合变量op、tr、cp的两个最高观测值。我希望得到dplyr的答案。我的原始 Dataframe 有成千上万个观测值,所以如果我想按年选择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

预期产出:

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年,高位停止按id = 1,第二个是id = 1和3,1986年是id = 1和3,1987年是id = 1和4,1988年是id = 1和4。
我想避免使用函数,但不确定是否可能。一个运行良好的函数应该是can。

2admgd59

2admgd591#

数据

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
46scxncf

46scxncf2#

使用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
f3temu5u

f3temu5u3#

您可以按降序排列group_byreframe/summariseacross列和sort值,并选择两个最大值,如下所示(请注意:使用na.rm = TRUE,因为第一个组只有1个值,因此选择两个值时,其中一个值为NA):

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年1月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)))
kr98yfug

kr98yfug4#

请尝试以下代码

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)

相关问题