2016-07-22 4 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 имеет значение 1 в FRQ колонки. Например, каждый rs4282783 имеет значение 1 в столбце FRQ, поэтому я хотел бы удалить все эти строки. Но я не хочу, например, удалить строку 58, которая имеет значение 1 в FRQ. У кого-нибудь есть совет?

ответ

2

Вот базовый метод R с использованием подмножества и ave. ave строит на уровне группы (СНП уровня) максимальный, который используется для подмножества данных путем наблюдения:

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

@ IMO о Ответ более аккуратный, но, как я сделал, я буду добавьте его. На мой взгляд, логика немного ясна.

# 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 not (!) all Элементы в 'FRQ' равны 1, затем получите подмножество Data.table.

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

Или общий подход, если можно предположить, что OP имел в виду, чтобы удалить все ОНП, имеющие только одну «FRQ», то мы можем использовать uniqueN, чтобы найти число unique элементов и использовать в условиях if к сохраняются только те, которые имеют более 1

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

Nice one. Когда у нас очень похожий подход, возможно, лучше оставить комментарий другим, чтобы мы могли интегрироваться в один и тот же ответ. +1 –

+0

@ StevenBeaupré Я думал, что синтаксис data.table может идти как отдельный ответ. – akrun

+1

@ StevenBeaupré Я добавил еще один подход – akrun

Смежные вопросы