2012-03-09 72 views
4

我按照多個標準跨多個列對數據框進行子集化。我選擇數據框中的行,其中包含三個不同列中任何一列中向量「條件」中定義的幾個值中的任何一個。R中的子集多列 - 更優雅的代碼?

我有一些可行的代碼,但不知道有什麼其他的(更優雅的?)方式來做到這一點。以下是我所做的:

criteria <-c(1:10) 
subset1 <-subset(data, data[, "Col1"] %in% criteria | data[, "Col2"] 
%in% criteria | data[, "Col3"] %in% criteria) 

建議熱烈歡迎。 (我是一名R初學者,所以對你的建議非常簡單的解釋也非常受歡迎。)

回答

13

我不知道,如果你需要這裏有兩個apply電話:

# Data 
df=data.frame(x=1:4,Col1=c(11,12,3,13),Col2=c(9,12,10,13),Col3=c(9,13,42,23)) 
criteria=1:10 

# Solution 
df[apply(df [c('Col1','Col2','Col3')],1,function(x) any(x %in% criteria)),] 

除非你想要做了很多列的,那麼它可能是更具可讀性說:

subset(df, Col1 %in% criteria | Col2 %in% criteria | Col3 %in% criteria) 
+0

請注意,子集的手冊頁警告不要以編程方式使用它,因爲它使用非標準評估 – richiemorrisroe 2012-03-10 10:54:26

+1

我在幫助頁面上閱讀了謹慎小心,但我不知道它的含義。爲什麼「非標準評估」成爲一個問題?就我而言,我只是將數據分段以創建一些描述性統計信息,所以我不認爲「子集」會對我造成問題......但是在什麼情況下會導致問題呢?謝謝。 – user1257313 2012-03-10 20:04:15

6

我使用DF而不是data作爲示例。

DF[apply(apply(as.matrix(DF[c("Col1","Col2","Col3")]), 
       c(1,2), `%in%`, criteria), 
     1, any),] 

對於這是什麼故障做:

使指定列的矩陣,並在矩陣測試每個元素,如果它包含的標準之一。然後對於該矩陣的每一行,查看是否有任何行元素是TRUE。如果是這樣,請保留原始數據集的相應行。

工作通過一個例子:

開始以虛擬數據:

DF <- data.frame(Col1=seq(1, by=2, length=10), 
       Col2=seq(3, by=3, length=10), 
       Col3=seq(7, by=1, length=10), 
       other=LETTERS[1:10]) 

它看起來像

> DF 
    Col1 Col2 Col3 other 
1  1 3 7  A 
2  3 6 8  B 
3  5 9 9  C 
4  7 12 10  D 
5  9 15 11  E 
6 11 18 12  F 
7 13 21 13  G 
8 15 24 14  H 
9 17 27 15  I 
10 19 30 16  J 

拉出的興趣只是列。

> as.matrix(DF[c("Col1","Col2","Col3")]) 
     Col1 Col2 Col3 
[1,] 1 3 7 
[2,] 3 6 8 
[3,] 5 9 9 
[4,] 7 12 10 
[5,] 9 15 11 
[6,] 11 18 12 
[7,] 13 21 13 
[8,] 15 24 14 
[9,] 17 27 15 
[10,] 19 30 16 

檢查每個條目相對於標準

> apply(as.matrix(DF[c("Col1","Col2","Col3")]), c(1,2), `%in%`, criteria) 
     Col1 Col2 Col3 
[1,] TRUE TRUE TRUE 
[2,] TRUE TRUE TRUE 
[3,] TRUE TRUE TRUE 
[4,] TRUE FALSE TRUE 
[5,] TRUE FALSE FALSE 
[6,] FALSE FALSE FALSE 
[7,] FALSE FALSE FALSE 
[8,] FALSE FALSE FALSE 
[9,] FALSE FALSE FALSE 
[10,] FALSE FALSE FALSE 

測試如果任何一列的值都是TRUE

> apply(apply(as.matrix(DF[c("Col1","Col2","Col3")]), c(1,2), `%in%`, criteria), 1, any) 
[1] TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE 

用它來索引的原始數據幀。

> DF[apply(apply(as.matrix(DF[c("Col1","Col2","Col3")]), c(1,2), `%in%`, criteria), 1, any),] 
    Col1 Col2 Col3 other 
1 1 3 7  A 
2 3 6 8  B 
3 5 9 9  C 
4 7 12 10  D 
5 9 15 11  E