2016-07-22 65 views
0

我有一個date.frame看起來像:如何有條件地刪除R中的行?

 SNP    CLST A1 A2  FRQ IMP  POS CHR BVAL 
1 rs2803291   Brahui C T 0.660000 0 1882185 1 878 
2 rs2803291   Balochi C T 0.750000 0 1882185 1 878 
3 rs2803291   Hazara C T 0.772727 0 1882185 1 878 
4 rs2803291   Makrani C T 0.620000 0 1882185 1 878 
5 rs2803291   Sindhi C T 0.770833 0 1882185 1 878 
6 rs2803291   Pathan C T 0.681818 0 1882185 1 878 
53 rs12060022   Brahui T C 0.0600000 1 3108186 1 982 
54 rs12060022   Balochi T C 0.0416667 1 3108186 1 982 
55 rs12060022   Hazara T C 0.0000000 1 3108186 1 982 
56 rs12060022   Makrani T C 0.0200000 1 3108186 1 982 
57 rs12060022   Sindhi T C 0.0625000 1 3108186 1 982 
58 rs12060022   Pathan T C 1   1 3108186 1 982 
105 rs870171   Brahui T G 0.2200000 0 3332664 1 976 
106 rs870171   Balochi T G 0.3333330 0 3332664 1 976 
107 rs870171   Hazara T G 1   0 3332664 1 976 
108 rs870171   Makrani T G 1   0 3332664 1 976 
109 rs870171   Sindhi T G 0.2083330 0 3332664 1 976 
110 rs870171   Pathan T G 1   0 3332664 1 976 
157 rs4282783   Brahui G T 1   1 4090545 1 992 
158 rs4282783   Balochi G T 1   1 4090545 1 992 
159 rs4282783   Hazara G T 1   1 4090545 1 992 
160 rs4282783   Makrani G T 1   1 4090545 1 992 
161 rs4282783   Sindhi G T 1   1 4090545 1 992 
162 rs4282783   Pathan G T 1   1 4090545 1 992 

我想刪除其中對於給定的SNP每一行已在FRQ列值爲1的所有行。例如,每個rs4282783在FRQ列中的值爲1,所以我想刪除所有這些行。但我不想刪除第58行,例如在FRQ中有1值。有人有建議嗎?

回答

2

這是使用子集和ave的基本R方法。 ave構建組級別(SNP電平)的最大值,其用於通過觀測到子集數據:

df[ave(df$FRQ, df$SNP, FUN=max) < 0.99999,] 

     SNP CLST A1 A2  FRQ IMP  POS CHR BVAL 
1 rs2803291 Brahui C T 0.660000 0 1882185 1 878 
2 rs2803291 Balochi C T 0.750000 0 1882185 1 878 
3 rs2803291 Hazara C T 0.772727 0 1882185 1 878 
4 rs2803291 Makrani C T 0.620000 0 1882185 1 878 
5 rs2803291 Sindhi C T 0.770833 0 1882185 1 878 
6 rs2803291 Pathan C T 0.681818 0 1882185 1 878 

注意,我爲了避免或減少的數值不精確性的問題使用0.99999而不是1。

數據

df <- read.table(header=T, text="SNP CLST A1 A2 FRQ IMP POS CHR BVAL 
1 rs2803291   Brahui C T 0.660000 0 1882185 1 878 
2 rs2803291   Balochi C T 0.750000 0 1882185 1 878 
3 rs2803291   Hazara C T 0.772727 0 1882185 1 878 
4 rs2803291   Makrani C T 0.620000 0 1882185 1 878 
5 rs2803291   Sindhi C T 0.770833 0 1882185 1 878 
6 rs2803291   Pathan C T 0.681818 0 1882185 1 878 
53 rs12060022   Brahui T C 0.0600000 1 3108186 1 982 
54 rs12060022   Balochi T C 0.0416667 1 3108186 1 982 
55 rs12060022   Hazara T C 0.0000000 1 3108186 1 982 
56 rs12060022   Makrani T C 0.0200000 1 3108186 1 982 
57 rs12060022   Sindhi T C 0.0625000 1 3108186 1 982 
58 rs12060022   Pathan T C 1   1 3108186 1 982 
105 rs870171   Brahui T G 0.2200000 0 3332664 1 976 
106 rs870171   Balochi T G 0.3333330 0 3332664 1 976 
107 rs870171   Hazara T G 1   0 3332664 1 976 
108 rs870171   Makrani T G 1   0 3332664 1 976 
109 rs870171   Sindhi T G 0.2083330 0 3332664 1 976 
110 rs870171   Pathan T G 1   0 3332664 1 976 
157 rs4282783   Brahui G T 1   1 4090545 1 992 
158 rs4282783   Balochi G T 1   1 4090545 1 992 
159 rs4282783   Hazara G T 1   1 4090545 1 992 
160 rs4282783   Makrani G T 1   1 4090545 1 992 
161 rs4282783   Sindhi G T 1   1 4090545 1 992 
162 rs4282783   Pathan G T 1   1 4090545 1 992") 
3

要刪除SNP其中FRQ所有值等於1,你可以嘗試:

library(dplyr) 
df %>% 
    group_by(SNP) %>% 
    filter(!all(FRQ == 1)) 

其中給出:

#   SNP CLST  A1  A2  FRQ IMP  POS CHR BVAL 
#  <fctr> <fctr> <fctr> <fctr>  <dbl> <int> <int> <int> <int> 
#1 rs2803291 Brahui  C  T 0.6600000  0 1882185  1 878 
#2 rs2803291 Balochi  C  T 0.7500000  0 1882185  1 878 
#3 rs2803291 Hazara  C  T 0.7727270  0 1882185  1 878 
#4 rs2803291 Makrani  C  T 0.6200000  0 1882185  1 878 
#5 rs2803291 Sindhi  C  T 0.7708330  0 1882185  1 878 
#6 rs2803291 Pathan  C  T 0.6818180  0 1882185  1 878 
#7 rs12060022 Brahui  T  C 0.0600000  1 3108186  1 982 
#8 rs12060022 Balochi  T  C 0.0416667  1 3108186  1 982 
#9 rs12060022 Hazara  T  C 0.0000000  1 3108186  1 982 
#10 rs12060022 Makrani  T  C 0.0200000  1 3108186  1 982 
#11 rs12060022 Sindhi  T  C 0.0625000  1 3108186  1 982 
#12 rs12060022 Pathan  T  C 1.0000000  1 3108186  1 982 
#13 rs870171 Brahui  T  G 0.2200000  0 3332664  1 976 
#14 rs870171 Balochi  T  G 0.3333330  0 3332664  1 976 
#15 rs870171 Hazara  T  G 1.0000000  0 3332664  1 976 
#16 rs870171 Makrani  T  G 1.0000000  0 3332664  1 976 
#17 rs870171 Sindhi  T  G 0.2083330  0 3332664  1 976 
#18 rs870171 Pathan  T  G 1.0000000  0 3332664  1 976 
2

@國際海事組織答案很整潔,但正如我所做的那樣,我會的添加它。 在我看來,邏輯更清晰一些。

# which SNPs are always 1 
# For each SNP value, take the rows with that SNP, and test if all FRQ values are 1 
rmSNPs <- sapply(unique(dd$SNP), function(x) all(dd$FRQ[dd$SNP == x] == 1)) 

# new data is old data minus row where dd$SNP is not one of those found above 
newdata <- dd[dd$SNP != unique(dd$SNP)[rmSNPs], ] 
2

這裏是基於data.table的方法。將'data.frame'轉換爲'data.table'(setDT(df)),按'SNP'分組,if不是(!all'FRQ'中的元素爲1,然後獲取Data.table的子集。

library(data.table) 
setDT(df)[, if(!(all(FRQ==1))) .SD , by = SNP] 

或一般的方法,如果我可以猜測,OP意味着刪除只具有單一「FRQ」,那麼我們就可以用uniqueN找到unique元素的數量,並在if條件下使用所有SNP只保留那些超過1

setDT(df)[, if(uniqueN(FRQ) > 1) .SD , by = SNP] 
+1

好的一個。當我們有非常相似的方法時,最好放棄其他評論,以便我們可以集成在相同的答案中。 +1 –

+0

@StevenBeaupré我認爲data.table語法可以作爲一個單獨的答案。 – akrun

+1

@StevenBeaupré我增加了另一種方法 – akrun