【问题标题】:select maximum row value by group按组选择最大行值
【发布时间】:2014-04-04 02:10:31
【问题描述】:

我一直在尝试通过查看其他帖子来处理我的数据,但我不断收到错误消息。我的数据new 如下所示:

id  year    name    gdp
1   1980    Jamie   45
1   1981    Jamie   60
1   1982    Jamie   70
2   1990    Kate    40
2   1991    Kate    25
2   1992    Kate    67
3   1994    Joe     35
3   1995    Joe     78
3   1996    Joe     90

我想按 id 选择具有最高年份值的行。所以想要的输出是:

id  year    name    gdp
1   1982    Jamie   70
2   1992    Kate    67
3   1996    Joe     90

来自Selecting Rows which contain daily max value in R 我尝试了以下但没有成功

ddply(new,~id,function(x){x[which.max(new$year),]})

我也试过了

tapply(new$year, new$id, max)

但这并没有给我想要的输出。

任何建议都会有帮助!

【问题讨论】:

    标签: r row max subset


    【解决方案1】:

    另一个适合大型表的选项是使用data.table。

    DT <- read.table(text = "id  year    name    gdp
                              1   1980    Jamie   45
                              1   1981    Jamie   60
                              1   1982    Jamie   70
                              2   1990    Kate    40
                              2   1991    Kate    25
                              2   1992    Kate    67
                              3   1994    Joe     35
                              3   1995    Joe     78
                              3   1996    Joe     90",
                     header = TRUE)
    
    require("data.table")
    DT <- as.data.table(DT)
    
    setkey(DT,id,year)
    res = DT[,j=list(year=year[which.max(gdp)]),by=id]
    res
    
    setkey(res,id,year)
    DT[res]
    # id year  name gdp
    # 1:  1 1982 Jamie  70
    # 2:  2 1992  Kate  67
    # 3:  3 1996   Joe  90
    

    【讨论】:

      【解决方案2】:

      只需使用split:

      df <- do.call(rbind, lapply(split(df, df$id),
        function(subdf) subdf[which.max(subdf$year)[1], ]))
      

      例如,

      df <- data.frame(id = rep(1:10, each = 3), year = round(runif(30,0,10)) + 1980, gdp = round(runif(30, 40, 70)))
      print(head(df))
      #   id year gdp
      # 1  1 1990  49
      # 2  1 1981  47
      # 3  1 1987  69
      # 4  2 1985  57
      # 5  2 1989  41
      # 6  2 1988  54
      
      df <- do.call(rbind, lapply(split(df, df$id), function(subdf) subdf[which.max(subdf$year)[1], ]))
      print(head(df))
      #    id year gdp
      # 1   1 1990  49
      # 2   2 1989  41
      # 3   3 1989  55
      # 4   4 1988  62
      # 5   5 1989  48
      # 6   6 1990  41
      

      【讨论】:

      • 老实说,这对于这项任务来说似乎过于复杂。你实际上是在用split+lapply重新创建by
      【解决方案3】:

      您可以通过duplicated 做到这一点

      # your data
       df <- read.table(text="id  year    name    gdp
      1   1980    Jamie   45
      1   1981    Jamie   60
      1   1982    Jamie   70
      2   1990    Kate    40
      2   1991    Kate    25
      2   1992    Kate    67
      3   1994    Joe     35
      3   1995    Joe     78
      3   1996    Joe     90" , header=TRUE)
      
      # Sort by id and year (latest year is last for each id)
      df <- df[order(df$id , df$year), ]
      
      # Select the last row by id
      df <- df[!duplicated(df$id, fromLast=TRUE), ]
      

      【讨论】:

        【解决方案4】:

        ave 再次在这里工作,并且将考虑到最大年份为多行的情况。

        new[with(new, year == ave(year,id,FUN=max) ),]
        
        #  id year  name gdp
        #3  1 1982 Jamie  70
        #6  2 1992  Kate  67
        #9  3 1996   Joe  90
        

        【讨论】:

          【解决方案5】:

          您的 ddply 工作在我看来不错,但您在回调函数中引用了原始数据集。

          ddply(new,~id,function(x){x[which.max(new$year),]})
          # should be
          ddply(new,.(id),function(x){x[which.max(x$year),]})
          

          【讨论】:

          • 似乎应该选择这个答案。
          猜你喜欢
          • 2022-06-23
          • 1970-01-01
          • 2023-01-04
          • 1970-01-01
          • 1970-01-01
          • 2013-07-22
          • 2018-09-10
          • 1970-01-01
          • 2014-08-24
          相关资源
          最近更新 更多