以某些标准为条件的子集表

时间:2014-03-25 16:38:15

标签: r

如果每个国家/地区的观察结果超过两次,那么该表中的一个子集怎么样呢?

+---------+---------+------------+
| Country | firm    |  DATE      |    
+---------+---------+------------+
| A       | ABC     | 4/20/2009  |
| A       | DEF     | 12/23/2003 | 
| A       | EFG     | 6/24/2010  | 
| A       | KLM     | 6/20/2001  | 
| C       | OPQ     | 5/23/2003  | 
| C       | RST     | 6/24/2001  | 
| B       | VWS     | 7/20/2007  | 
| B       | ART     | 6/23/2003  | 
| C       | PUO     | 8/24/2002  |       
+---------+---------+------------+

结果应该是这样的:

+---------+---------+------------+
| Country | firm    |  DATE      |    
+---------+---------+------------+
| A       | ABC     | 4/20/2009  |
| A       | DEF     | 12/23/2003 | 
| A       | EFG     | 6/24/2010  | 
| A       | KLM     | 6/20/2001  | 
| C       | OPQ     | 5/23/2003  | 
| C       | RST     | 6/24/2001  | 
| C       | PUO     | 8/24/2002  |       
+---------+---------+------------+

3 个答案:

答案 0 :(得分:2)

您可以ave使用length作为功能。假设您的data.frame被称为“mydf”,请尝试:

ave(rep(1, nrow(mydf)), mydf$Country, FUN = length)
# [1] 4 4 4 4 3 3 2 2 3
mydf[ave(rep(1, nrow(mydf)), mydf$Country, FUN = length) > 2, ]
#   Country firm       DATE
# 1       A  ABC  4/20/2009
# 2       A  DEF 12/23/2003
# 3       A  EFG  6/24/2010
# 4       A  KLM  6/20/2001
# 5       C  OPQ  5/23/2003
# 6       C  RST  6/24/2001
# 9       C  PUO  8/24/2002

ave与R中的许多其他聚合函数略有不同,因为它返回与输入长度相同的向量,并根据组重复值。这使得它非常适合这样的事情,我们最终希望根据列表值进行子集化。我将ave和第一个参数用作rep(1, nrow(mydf))只是为了避免必须转换为字符,然后在我们正在进行制表时将其转换为数字。


但更好的是使用“dplyr”:

library(dplyr)
mydf %.%
  group_by(Country) %.%
  filter(n() > 2)
# Source: local data frame [7 x 3]
# Groups: Country
# 
#   Country firm       DATE
# 1       A  ABC  4/20/2009
# 2       A  DEF 12/23/2003
# 3       A  EFG  6/24/2010
# 4       A  KLM  6/20/2001
# 5       C  OPQ  5/23/2003
# 6       C  RST  6/24/2001
# 7       C  PUO  8/24/2002

“dplyr”语法可能需要习惯,但如果你花时间,你可能会发现它非常直观。

三条线(每条线由%.%分隔)基本上说:

  1. 我们正在使用data.frame“mydf”......
  2. 我们将data.frame分组为“国家/地区”列...
  3. 我们filter选择计数(使用“dplyr”中的内置n()函数计算)大于2的任何行...

  4. 当然,还有“data.table”:

    library(data.table)
    DT <- data.table(mydf)                  # Convert to a "data.table"
    DT[, N := .N, by = country][N > 100, ]  # Tabulate and subset
    

答案 1 :(得分:2)

假设dat是数据表的名称,

> dat[dat$Country %in% names(which(table(dat$Country) > 2)), ]
##   Country firm       DATE
## 1       A  ABC  4/20/2009
## 2       A  DEF 12/23/2003
## 3       A  EFG  6/24/2010
## 4       A  KLM  6/20/2001
## 5       C  OPQ  5/23/2003
## 6       C  RST  6/24/2001
## 9       C  PUO  8/24/2002

答案 2 :(得分:0)

尝试使用subset

> subset(dat, dat$Country %in% with(dat, levels(Country)[table(Country)>2]) )
  Country firm       DATE
1       A  ABC  4/20/2009
2       A  DEF 12/23/2003
3       A  EFG  6/24/2010
4       A  KLM  6/20/2001
5       C  OPQ  5/23/2003
6       C  RST  6/24/2001
9       C  PUO  8/24/2002

另一种(长期)方式

> do.call(rbind,sapply(split(dat, dat$Country), function(x) x[length(x$Country)>2]))
    Country firm       DATE
A.1       A  ABC  4/20/2009
A.2       A  DEF 12/23/2003
A.3       A  EFG  6/24/2010
A.4       A  KLM  6/20/2001
C.5       C  OPQ  5/23/2003
C.6       C  RST  6/24/2001
C.9       C  PUO  8/24/2002