R中每组第k_th个最小元素

时间:2019-05-10 21:10:22

标签: r sorting

我有一个数据表dt,看起来像

   location year value
       NYC 2026     1
       NYC 2026     2
       NYC 2026     3
       NYC 2026     4
       NYC 2026     5
        LA 2026     6
        LA 2026     7
        LA 2026     8
        LA 2026     9
        LA 2026    10

我想按cityyear对它们进行分组,并在其中找到第二小的元素 每个组的value列中,所需结果如下:

   location year value
        NYC  2026     2
         LA  2026     7

dt %>% grou_by(location, year) %>% nth(value, 2)

不起作用。任何帮助表示赞赏。

上面的数据表可以通过以下方式创建:

dt <- structure(list(location = c("NYC", "NYC", "NYC","NYC", "NYC", 
                                   "LA", "LA", "LA", "LA", "LA"), 
                 year = c(2026, 2026, 2026, 2026, 2026,
                          2026, 2026, 2026, 2026, 2026),
                 value = c(1, 2, 3, 4, 5,
                           6, 7, 8, 9, 10)),
                 class = "data.table", 
                 row.names = c(NA, -10L))

3 个答案:

答案 0 :(得分:6)

一种ParentName Department From To FromAmount ToAmount XYZ 101 Name1 Name2 -2 2 ABC 102 Name2 Name4 -200 200 ABC 102 Name3 Name4 -200 200 ABC 102 Name9 Name4 -200 200 PQR 103 Name5 Name3 -250 250 PQR 103 Name5 Name6 -250 250 BBB 104 Name7 Name10 -50 75 BBB 104 Name8 Name11 -100 75 可能是:

dplyr

此处按“位置”列进行分组,并根据“值”列排列值,然后保留第二个元素。

df %>%
 group_by(location) %>%
 arrange(value) %>%
 slice(2)

或者如果“值”列中的值可以重复,则可以执行以下操作:

  location  year value
  <chr>    <int> <int>
1 LA        2026     7
2 NYC       2026     2

或者使用df %>% group_by(location) %>% distinct(value, .keep_all = TRUE) %>% arrange(value) %>% slice(2) ,而不是filter()

slice()

同样的考虑也可能重复:

df %>%
 group_by(location) %>%
 arrange(value) %>%
 filter(row_number() == 2)

或使用df %>% group_by(location) %>% distinct(value, .keep_all = TRUE) %>% arrange(value) %>% filter(row_number() == 2) filter()

dense_rank()

同样的考虑也可能重复:

df %>%
 group_by(location) %>%
 filter(dense_rank(value) == 2)

答案 1 :(得分:4)

使用summarizegroup_by一起使用:

> dt %>% group_by(location, year) %>% arrange(value) %>%  summarize(value = nth(value, 2))
# A tibble: 2 x 3
# Groups:   location [2]
  location  year value
  <chr>    <dbl> <dbl>
1 LA        2026     7
2 NYC       2026     2

答案 2 :(得分:1)

由于只需要2nd元素,所以部分排序不应该成为问题。我不知道dplyrdata.table是否支持它,但是它具有基本R排序(带有受限制的选项),例如。

with(dt, lapply(split(dt, interaction(location, year)), 
  function(x) sort.int(x$value, partial=2)))

我怀疑即使优化后对它们进行完全排序,它也将比dplyrdata.table更快,但是也许值得关注效率。

哦,您还可以先进行排序,然后进行分组,然后简单地从每个分组中选择第n个值,为每个组保存多个排序例程。