R. Удалить блоки наблюдений в df, если они выполняют условие

#r #dataframe

#r #фрейм данных

Вопрос:

У меня есть огромный фрейм данных (> 1 000 000 строк), подобный этому.

 term    estimate    st.error    statistic    p.value    SNP
(Intercept)    7.68    0.17    44.64    0    rs1406947
GT    0.01    0.01    0.07    0.19    rs1406947     
SEX    1.52    0.14    10.87    0.1    rs1406947 
M    0.12    0.29    0.41    0.67    rs1406947   
N    -0.06    0.12    -0.48    0.63    rs1406947
GT:SEX    -0.03    0.08    -0.44    0.65    rs1406947
GT:N    -0.00    0.06    -0.08    0.93    rs1406947   
(Intercept)    9.23    0.20    34.64    0    rs25904
GT    0.05    0.04    0.12    0.22    rs25904    
SEX    1.67    0.76    10.34    0.1    rs25904 
M    0.14    0.39    0.51    0.55    rs25904   
N    -0.08    0.05    -0.46    0.55    rs25904
GT:SEX    -0.19    0.11    -0.34    0.44    rs25904
GT:N    -0.22    0.33    -0.44    0.55    rs25904           
(Intercept)    7.99    0.66    44.44    0    rs7133579
GT    0.01    0.3    0.04    0.33    rs7133579    
SEX    1.22    0.22    10.44    0.15    rs7133579 
M    0.88    0.22    0.33    0.44    rs7133579   
N    -0.5    0.5    -0.5    0.6    rs7133579
GT:N    -0.00    0.03    -0.04    0.78    rs7133579 
  

Он состоит из блоков по 7 наблюдений: (Перехват), GT, SEX, M, N, GT:SEX и GT:N. Однако в нескольких блоках отсутствует одно или несколько наблюдений (например, в третьем блоке отсутствует GT:SEX). Используя R, я хочу удалить эти блоки. В этом игрушечном примере я бы получил:

 term    estimate    st.error    statistic    p.value    SNP
(Intercept)    7.68    0.17    44.64    0    rs1406947
GT    0.01    0.01    0.07    0.19    rs1406947     
SEX    1.52    0.14    10.87    0.1    rs1406947 
M    0.12    0.29    0.41    0.67    rs1406947   
N    -0.06    0.12    -0.48    0.63    rs1406947
GT:SEX    -0.03    0.08    -0.44    0.65    rs1406947
GT:N    -0.00    0.06    -0.08    0.93    rs1406947   
(Intercept)    9.23    0.20    34.64    0    rs25904
GT    0.05    0.04    0.12    0.22    rs25904    
SEX    1.67    0.76    10.34    0.1    rs25904 
M    0.14    0.39    0.51    0.55    rs25904   
N    -0.08    0.05    -0.46    0.55    rs25904
GT:SEX    -0.19    0.11    -0.34    0.44    rs25904
GT:N    -0.22    0.33    -0.44    0.55    rs25904           
  

Комментарии:

1. Пожалуйста, сделайте ваши примеры данных воспроизводимыми.

Ответ №1:

Я думаю, вы хотели бы сгруппировать по SNP и проверить эти блоки на соответствие вашим ожиданиям:

 library(dplyr)

expected_terms <- c("(Intercept)", "GT", "SEX", "M", "N", "GT:SEX", "GT:N")

df %>%
  group_by(SNP) %>%
  filter(
    all(expected_terms %in% term)
  )
  

Более строго, если вам нужно убедиться, что каждый из ваших терминов существует только один раз или другие термины не отображаются:

 df %>%
  group_by(SNP) %>%
  filter(
    # use `table` to count occurrence of terms, keep only if all are counted exactly once
    all(table(term)[expected_terms] == 1),
    # keep only if no terms remain after removing your expected set
    length(setdiff(term, expected_terms)) == 0
  )
  

Ответ №2:

Предполагая, что это (Intercept) присутствует каждый раз, вы можете проверить, является ли length каждого блока 7 .

 x[unlist(lapply(split(seq_len(nrow(x)), cumsum(x$term == "(Intercept)")),
                function(y) {if(length(y) == 7) y else NULL})), ]
#          term estimate st.error statistic p.value       SNP
#1  (Intercept)     7.68     0.17     44.64    0.00 rs1406947
#2           GT     0.01     0.01      0.07    0.19 rs1406947
#3          SEX     1.52     0.14     10.87    0.10 rs1406947
#4            M     0.12     0.29      0.41    0.67 rs1406947
#5            N    -0.06     0.12     -0.48    0.63 rs1406947
#6       GT:SEX    -0.03     0.08     -0.44    0.65 rs1406947
#7         GT:N     0.00     0.06     -0.08    0.93 rs1406947
#8  (Intercept)     9.23     0.20     34.64    0.00   rs25904
#9           GT     0.05     0.04      0.12    0.22   rs25904
#10         SEX     1.67     0.76     10.34    0.10   rs25904
#11           M     0.14     0.39      0.51    0.55   rs25904
#12           N    -0.08     0.05     -0.46    0.55   rs25904
#13      GT:SEX    -0.19     0.11     -0.34    0.44   rs25904
#14        GT:N    -0.22     0.33     -0.44    0.55   rs25904
  

Данные:

 x <- read.table(header=TRUE, text="term    estimate    st.error    statistic    p.value    SNP
(Intercept)    7.68    0.17    44.64    0    rs1406947
GT    0.01    0.01    0.07    0.19    rs1406947     
SEX    1.52    0.14    10.87    0.1    rs1406947 
M    0.12    0.29    0.41    0.67    rs1406947   
N    -0.06    0.12    -0.48    0.63    rs1406947
GT:SEX    -0.03    0.08    -0.44    0.65    rs1406947
GT:N    -0.00    0.06    -0.08    0.93    rs1406947   
(Intercept)    9.23    0.20    34.64    0    rs25904
GT    0.05    0.04    0.12    0.22    rs25904    
SEX    1.67    0.76    10.34    0.1    rs25904 
M    0.14    0.39    0.51    0.55    rs25904   
N    -0.08    0.05    -0.46    0.55    rs25904
GT:SEX    -0.19    0.11    -0.34    0.44    rs25904
GT:N    -0.22    0.33    -0.44    0.55    rs25904           
(Intercept)    7.99    0.66    44.44    0    rs7133579
GT    0.01    0.3    0.04    0.33    rs7133579    
SEX    1.22    0.22    10.44    0.15    rs7133579 
M    0.88    0.22    0.33    0.44    rs7133579   
N    -0.5    0.5    -0.5    0.6    rs7133579
GT:N    -0.00    0.03    -0.04    0.78    rs7133579")