【问题标题】:Subset panel data by group [duplicate]按组的子集面板数据[重复]
【发布时间】:2015-03-31 19:15:33
【问题描述】:

我想按组对不平衡面板数据集进行子集化。对于每个组,我想保留第一年和最后几年的两个观察结果。

如何在 R 中最好地做到这一点?例如:

dt <- data.frame(name= rep(c("A", "B", "C"), c(3,2,3)), 
                 year=c(2001:2003,2000,2002,2000:2001,2003))

> dt
  name year
1    A 2001
2    A 2002
3    A 2003
4    B 2000
5    B 2002
6    C 2000
7    C 2001
8    C 2003

我想要什么:

  name year
1    A 2001
3    A 2003
4    B 2000
5    B 2002
6    C 2000
8    C 2003

【问题讨论】:

    标签: r panel subset


    【解决方案1】:

    应该会有所帮助。查看 first() 和 last() 以获取您要查找的值,然后根据这些值进行过滤。

    dt <- data.frame(name= rep(c("A", "B", "C"), c(3,2,3)), year=c(2001:2003,2000,2002,2000:2001,2003))
    
    library(dplyr)
    
    dt %>%
      group_by(name) %>%
      mutate(first = first(year)
            ,last = last(year)) %>%
      filter(year == first | year == last) %>%
      select(name, year)
    
      name year
    1    A 2001
    2    A 2003
    3    B 2000
    4    B 2002
    5    C 2000
    6    C 2003
    

    *你的例子没有提到任何具体的顺序,但在这种情况下,arrange() 会有所帮助

    【讨论】:

    • 谢谢。但似乎 dplyr 不再可用。
    • @加里:??? cran.r-project.org/web/packages/dplyr/index.html 很有可能你有一个旧版本的 R 没有看到这个包......
    • @BenBolker 我的猜测是 OP 不知道他可以安装外部软件包,例如使用install.packages("dplyr")
    【解决方案2】:

    这是一个可能的快速data.table 解决方案

    library(data.table)
    setDT(dt)[, .SD[c(1L, .N)], by = name]
    #    name year
    # 1:    A 2001
    # 2:    A 2003
    # 3:    B 2000
    # 4:    B 2002
    # 5:    C 2000
    # 6:    C 2003
    

    或者如果你只有两列

    dt[, year[c(1L, .N)], by = name]
    

    【讨论】:

      【解决方案3】:

      这很简单,使用by 按组拆分data.frame,然后返回每个组的头部和尾部。

      > do.call(rbind, by(dt, dt$name, function(x) rbind(head(x,1),tail(x,1))))
          name year
      A.1    A 2001
      A.3    A 2003
      B.4    B 2000
      B.5    B 2002
      C.6    C 2000
      C.8    C 2003
      

      headtail 很方便,但速度很慢,所以稍微不同的替代方案在大型数据帧上可能会更快:

      do.call(rbind, by(dt, dt$name, function(x) x[c(1,nrow(x)),]))
      

      【讨论】:

      • 谢谢!这个解决方案很完美!
      • dt[as.logical(ave(dt$year,dt$name,FUN=function(x) seq_along(x) %in% c(1,length(x)))),] 作为替代使用 ave
      猜你喜欢
      • 2017-08-23
      • 1970-01-01
      • 2014-09-12
      • 1970-01-01
      • 2017-09-01
      • 2020-07-22
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      相关资源
      最近更新 更多