【问题标题】:Conditional calculating Maximum value in the column条件计算列中的最大值
【发布时间】:2014-11-06 03:41:42
【问题描述】:

我有下表:

Class  x2  x3  x4
  A    14  45  53 
  A     8  18  17
  A    16  49  20
  B    78  21  48 
  B     8  18   5

我需要为每个“类”(A 和 B)在“X3”列中找到最大值,保留该行并删除其他行。

输出格式应如下:

Class  x2  x3  x4
  A    14  49  20
  B    78  21  48 

如果我的问题不清楚,请向我提问。

谢谢!

【问题讨论】:

  • 在平局的情况下,您的预期结果是什么?即如果在列 x3 中的第一个和第三个条目都是 49?

标签: r aggregate apply


【解决方案1】:

基本的 R 方法可能是:

mydf[as.logical(with(mydf, ave(x3, Class, FUN = function(x) x == max(x)))), ]
#   Class x2 x3 x4
# 3     A 16 49 20
# 4     B 78 21 48

但是,请注意,如果有多个值与 max 相关联,它将为该组返回多行。


这是一种可能的“data.table”方法:

library(data.table)
setkey(as.data.table(mydf), Class, x3)[, tail(.SD, 1), by = Class]
#    Class x2 x3 x4
# 1:     A 16 49 20
# 2:     B 78 21 48

【讨论】:

  • 考虑绑定的最大值非常好。很周到。 +1 :)
  • @jazzurro,但问题没有提供足够的信息来说明这是否可取:-)
【解决方案2】:

这是另一个dplyr 的答案

library(dplyr)
df %>% group_by(Class) %>% filter(x3 == max(x3))
# Source: local data frame [2 x 4]
# Groups: Class
# 
#   Class x2 x3 x4
# 1     A 16 49 20
# 2     B 78 21 48

也可以是

group_by(df, Class) %>% filter(x3 == max(x3))

【讨论】:

  • 这样就不需要dense_rank了。你的第一个 dplyr 答案? +1 :)
  • 我的第二个。第一个被否决了,我删除了它。哈哈。我决定学习更多地使用dplyr。我真的很喜欢这种管道的东西。而且代码真的很干净。
  • 我们都是这样的,不是吗?犯错并学习更多!前几天我误读了一个与字符串有关的问题并被否决了;我立即道歉并删除了我的答案。
  • 您可能已经拥有此材料。如果没有,这对 dplyr 将非常有用。我一直用这个作为参考。检查this
【解决方案3】:

使用dplyr 的一种方法是:

library(dplyr)

foo %>%
    #For each Class
    group_by(Class) %>%
    # Sort rows in descending way using x3: you get the max x3 value on top
    # for each group
    arrange(desc(x3)) %>%
    # Select the first row for each Class
    slice(1)

#  Class x2 x3 x4
#1     A 16 49 20
#2     B 78 21 48

编辑 鉴于@Ananda 的 tie-values 考虑和他在评论中的建议, 你也可以做这样的事情。但是,@Richard Acriven 的想法是 走的路,如果有关系。

# Data
foo2 <- structure(list(Class = structure(c(1L, 1L, 1L, 2L, 2L), .Label = c("A", 
"B"), class = "factor"), x2 = c(14L, 8L, 16L, 78L, 8L), x3 = c(49L, 
18L, 49L, 21L, 18L), x4 = c(53L, 17L, 20L, 48L, 5L)), .Names = c("Class", 
"x2", "x3", "x4"), class = "data.frame", row.names = c(NA, -5L
))

#  Class x2 x3 x4
#1     A 14 49 53
#2     A  8 18 17
#3     A 16 49 20
#4     B 78 21 48
#5     B  8 18  5  

foo2 %>% 
   group_by(Class) %>% 
   mutate(Rank = dense_rank(desc(x3))) %>%
   filter(Rank == 1)

#  Class x2 x3 x4 Rank
#1     A 14 49 53    1
#2     A 16 49 20    1
#3     B 78 21 48    1

【讨论】:

  • +1。我很少使用“dplyr”,但slice 似乎可以解决问题。
  • @AnandaMahto 如果slice 可以打领带,那就太好了。
  • "dplyr" 有很好的rank 选项,在这里可能很有用。
  • @AnandaMahto 没错! dense_rank 我想。让我玩它。 :)
  • 最后一件事,如果您像在第二个解决方案中那样使用dense_rank,您可以避免变异并在过滤器foo2 %&gt;% group_by(Class) %&gt;% filter(dense_rank(desc(x3)) == 1) 中使用dense_rank。当您需要创建一个用于对数据进行分组的新列时,您可以在 group_by 中执行相同的操作。
【解决方案4】:

试试:

do.call(rbind, lapply(split(ddf, ddf$Class), function(x) tail(x[order(x$x3),],1)))
  Class x2 x3 x4
A     A 16 49 20
B     B 78 21 48

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-13
    • 1970-01-01
    • 2021-06-21
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 2014-09-27
    相关资源
    最近更新 更多