R group by key获取多列的最大值

时间:2018-03-07 19:40:49

标签: r data.table

我想做这样的事情:

How to make a unique in R by column A and keep the row with maximum value in column B

除了我的data.table有一个关键列和多个值列。所以说我有以下内容:

   a b c
1: 1 1 1
2: 1 2 1
3: 1 2 2
4: 2 1 1
5: 2 2 5
6: 2 3 3
7: 3 1 4
8: 3 2 1

如果密钥是列a,我希望每个唯一a都返回最大b行,并且如果有多个唯一最大b获取具有最大c的那个,依此类推多列。所以结果应该是:

   a b c
1: 1 2 2
2: 2 3 3
3: 3 2 1

我也希望对任意数量的列进行此操作。因此,如果我的data.table有20列,我希望从左到右按顺序应用max函数。

4 个答案:

答案 0 :(得分:1)

要使此功能适用于任意数量的列,可能的dplyr解决方案是使用arrange_all

df <- data.frame(a = c(1,1,1,2,2,2,3,3), b = c(1,2,2,1,2,3,1,2),
                 c = c(1,1,2,1,5,3,4,1))

df %>% group_by(a) %>% arrange_all() %>% filter(row_number() == n())

# A tibble: 3 x 3
# Groups:   a [3]
#       a     b     c
# 1     1     2     2
# 2     2     3     3
# 3     3     2     1

答案 1 :(得分:1)

这是一个建议的data.table解决方案。您可能需要考虑使用data.table::frankv,如下所示:

DT[, .SD[frankv(.SD, ties.method="first")[.N],], by=a]

frankv返回订单。然后[.N]将获得最大排名。然后.SD[子集到该特定行。

如果您的大型数据集失败,请告诉我。

答案 2 :(得分:0)

使用mutate_at可以在任意数量的列中实现通用解决方案。在下面的示例中,c("a","b","c")是任意列。

library(dplyr)
df %>% arrange_at(.vars = vars(c("a","b","c"))) %>%
  mutate(changed = ifelse(a != lead(a), TRUE, FALSE)) %>%
  filter(is.na(changed) | changed ) %>%
  select(-changed)

  a b c
1 1 2 2
2 2 3 3
3 3 2 1

另一种选择可能是使用maxdplyr,如下所示。方法是group_by上的a,然后过滤max的{​​{1}}值。 bgroup_by上再次a,并过滤b值为max的行。

c

数据

library(dplyr)

df %>% group_by(a) %>%
  filter(b == max(b)) %>%
  group_by(a, b) %>%
  filter(c == max(c))



# Groups: a, b [3]
#      a     b     c
#  <int> <int> <int>
#1     1     2     2
#2     2     3     3
#3     3     2     1

答案 3 :(得分:0)

dat <- data.frame(a = c(1,1,1,2,2,2,3,3),
                  b = c(1,2,2,1,2,3,1,2),
                  c = c(1,1,2,1,5,3,4,1))

library(sqldf)
sqldf("with d as (select * from 'dat' group by a order by b, c desc) select * from d order by a")

  a b c
1 1 2 2
2 2 3 3
3 3 2 1