【问题标题】:Select a value for based on a highest value in another column根据另一列中的最大值选择一个值
【发布时间】:2012-05-29 03:16:27
【问题描述】:

我不明白为什么我找不到解决方案,因为我觉得这是一个非常基本的问题。那就需要求助了。我想按月重新排列空气质量数据集,每个月的最大温度值。另外我想找到每个月最高气温对应的日子。执行此操作的最懒惰(代码方面)的方法是什么?

我尝试了以下但没有成功:

require(reshape2)
names(airquality) <- tolower(names(airquality))
mm <- melt(airquality, id.vars = c("month", "day"), meas = c("temp"))

dcast(mm, month + day ~ variable, max)
aggregate(formula = temp ~ month + day, data = airquality, FUN = max)

我追求的是这样的:

month day temp
5     7    89
...

【问题讨论】:

    标签: r reshape2


    【解决方案1】:

    plyr 怎么样?

    max.func <- function(df) {
       max.temp <- max(df$temp)
    
       return(data.frame(day = df$Day[df$Temp==max.temp],
                         temp = max.temp))
    }
    
    ddply(airquality, .(Month), max.func)
    

    如您所见,本月的最高温度不止一天。如果您想要不同的行为,该功能很容易调整。

    【讨论】:

      【解决方案2】:

      或者如果你想使用data.table 包(例如,如果速度是一个问题并且数据集很大或者如果你更喜欢语法):

      library(data.table)
      DT <- data.table(airquality)
      DT[, list(maxTemp=max(Temp), dayMaxTemp=.SD[max(Temp)==Temp, Day]), by="Month"]
      

      如果你想知道.SD 代表什么,请看这里:SO

      【讨论】:

      • 我认为你在那一次上打败了我 :)
      • 在时间方面,是的,提前两秒(庆祝的时间 ;-) 但是你的 which.max 技巧很巧妙......所以+1!
      【解决方案3】:

      前段时间关于懒惰是好还是坏的讨论颇多。 Anwyay,这写和读都很简短自然(并且对于大数据来说很快,所以你以后不需要更改或优化它):

      require(data.table)
      DT=as.data.table(airquality)
      
      DT[,.SD[which.max(Temp)],by=Month]
      
           Month Ozone Solar.R Wind Temp Day
      [1,]     5    45     252 14.9   81  29
      [2,]     6    NA     259 10.9   93  11
      [3,]     7    97     267  6.3   92   8
      [4,]     8    76     203  9.7   97  28
      [5,]     9    73     183  2.8   93   3
      

      .SD 是每个组的数据子集,您只需要其中具有最大 Temp 的行,iiuc。如果您需要行号,则可以添加。

      或者获取最大值绑定的所有行:

      DT[,.SD[Temp==max(Temp)],by=Month]
      
           Month Ozone Solar.R Wind Temp Day
      [1,]     5    45     252 14.9   81  29
      [2,]     6    NA     259 10.9   93  11
      [3,]     7    97     267  6.3   92   8
      [4,]     7    97     272  5.7   92   9
      [5,]     8    76     203  9.7   97  28
      [6,]     9    73     183  2.8   93   3
      [7,]     9    91     189  4.6   93   4
      

      【讨论】:

      • 谢谢大家!我之前没有使用过 data.table 包,所以它是一个时间。 “答案已接受”,因为这是最完整的(并且比 Chritoph_J 的略短)。不过,你们所有人都应该得到它(每个人都 +1)。
      • 我想知道是否有任何语言的更简洁的解决方案。我猜不是。
      【解决方案4】:

      使用 plyr 的另一种方法

      require(reshape2)
      names(airquality) <- tolower(names(airquality))
      mm <- melt(airquality, id.vars = c("month", "day"), meas = c("temp"), value.name = 'temp')
      
      library(plyr)
      
      ddply(mm, .(month), subset, subset = temp == max(temp), select = -variable)
      

      给予

        month day temp
      1     5  29   81
      2     6  11   93
      3     7   8   92
      4     7   9   92
      5     8  28   97
      6     9   3   93
      7     9   4   93
      

      或者,更简单

      require(reshape2)
      require(plyr)
      names(airquality) <- tolower(names(airquality))
      ddply(airquality, .(month), subset, 
        subset = temp == max(temp), select = c(month, day, temp) )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-25
        • 2018-01-02
        • 2014-10-05
        • 2018-08-25
        • 2023-03-23
        • 2022-09-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多