2014-03-25 37 views
0

這張表只有一個子集,如果每個國家有兩個以上的觀察值,那麼這個子集又該如何呢?子集有條件的一些條件

+---------+---------+------------+ 
| 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 |  
+---------+---------+------------+ 
+0

此佈局是在R中完成還是您手動添加分隔線和分隔符?我在Python中用'prettytable'看過這個,但是從來沒有在R. – maloneypatr

+0

@maloneypatr我不應該對這張表做任何評價。我只是從別人那裏拿過這張桌子,並將它改編爲我的。可恥的是我不記得這篇文章,但是我感謝作者,不管它是誰。 – DJJ

回答

2

您可以使用avelength的功能。假設你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 ING選擇任何行,其中計數(在「dplyr」的內置功能n()計算)大於2 ...

有,當然,也是 「data.table」:

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

+1!我喜歡你的'plyr'解決方案。 –

+0

你好,謝謝你的回答。兩種解決方案確實都很有效一見鍾情,他們似乎並不直觀。是否可以爲第二個添加一些解釋? – DJJ

+0

@DJJ,編輯。讓我知道是否還有其他問題。 – A5C1D2H2I1M1N2O1R2T1

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 
+0

我發現''by'有點可讀性:'do.call(rbind,by(mydf,mydf $ Country,FUN = function(x)x [nrow(x)> 2,]))''。 – A5C1D2H2I1M1N2O1R2T1

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 
+0

這是我會寫的答案。清潔和簡單。 – Rufo

+0

更直觀。 – DJJ