Gostaria de remover as linhas neste quadro de dados que:
a) contém NA
s em todas as colunas. Abaixo está o meu exemplo de quadro de dados.
gene hsap mmul mmus rnor cfam
1 ENSG00000208234 0 NA NA NA NA
2 ENSG00000199674 0 2 2 2 2
3 ENSG00000221622 0 NA NA NA NA
4 ENSG00000207604 0 NA NA 1 2
5 ENSG00000207431 0 NA NA NA NA
6 ENSG00000221312 0 1 2 3 2
Basicamente, gostaria de obter um quadro de dados como o seguinte.
gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
6 ENSG00000221312 0 1 2 3 2
b) contém NA
s em apenas algumas colunas , para que eu também possa obter este resultado:
gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
4 ENSG00000207604 0 NA NA 1 2
6 ENSG00000221312 0 1 2 3 2
final[complete.cases(final),]
?complete.cases
? Se eu quisesse manter as linhas com os NAs em vez de descartar?final[ ! complete.cases(final),]
não coopera ...final
é o dataframe variável?Tente
na.omit(your.data.frame)
. Quanto à segunda pergunta, tente postá-la como outra pergunta (para maior clareza).fonte
rownames(x) <- NULL
.na.omit()
cai linhas que contêmNA
em qualquer colunatidyr
tem uma nova funçãodrop_na
:fonte
drop_na
. Por exemplo,df %>% drop_na()
,df %>% na.omit()
edrop_na(df)
são todos basicamente equivalente.na.omit
adiciona informações adicionais, como os índices de casos omitidos, e - o mais importante - não permite selecionar colunas - é aqui quedrop_na
brilha.na.omit
com ou sem tubos, assim como você pode usardrop_na
com ou sem tubos.Prefiro seguir a maneira de verificar se as linhas contêm NAs:
Isso retorna um vetor lógico com valores que indicam se existe algum NA em uma linha. Você pode usá-lo para ver quantas linhas você precisará eliminar:
e, eventualmente, largá-los
Para filtrar linhas com certa parte das NAs, fica um pouco mais complicado (por exemplo, você pode alimentar 'final [, 5: 6]' para 'aplicar'). Geralmente, a solução de Joris Meys parece ser mais elegante.
fonte
rowSum(!is.na(final))
parece mais adequado do queapply()
Outra opção se você deseja maior controle sobre como as linhas são consideradas inválidas é
Usando o acima, isto:
Torna-se:
... onde apenas a linha 5 é removida, pois é a única linha que contém NAs para
rnor
ANDcfam
. A lógica booleana pode ser alterada para atender a requisitos específicos.fonte
Se você deseja controlar quantas NAs são válidas para cada linha, tente esta função. Para muitos conjuntos de dados de pesquisa, muitas respostas em branco às perguntas podem arruinar os resultados. Portanto, eles são excluídos após um certo limite. Esta função permitirá que você escolha quantas NAs a linha pode ter antes de ser excluída:
Por padrão, ele eliminará todos os NAs:
Ou especifique o número máximo de NAs permitido:
fonte
Se o desempenho for uma prioridade, use
data.table
ena.omit()
com parâmetros opcionaiscols=
.na.omit.data.table
é o mais rápido no meu benchmark (veja abaixo), seja para todas as colunas ou para as colunas selecionadas (pergunta OP parte 2).Se você não quiser usar
data.table
, usecomplete.cases()
.Em uma baunilha
data.frame
,complete.cases
é mais rápido quena.omit()
oudplyr::drop_na()
. Observe quena.omit.data.frame
não suportacols=
.Resultado de referência
Aqui está uma comparação dos métodos base (azul),
dplyr
(rosa) edata.table
(amarelo) para descartar todas ou selecionar observações ausentes, no conjunto de dados nocional de 1 milhão de observações de 20 variáveis numéricas com probabilidade independente de 5% de estar ausente e um subconjunto de 4 variáveis para a parte 2.Seus resultados podem variar com base no comprimento, largura e esparsidade do seu conjunto de dados específico.
Observe a escala do log no eixo y.
Script de benchmark
fonte
Usando o pacote dplyr, podemos filtrar o NA da seguinte maneira:
fonte
drop_na()
Isso retornará as linhas que possuem pelo menos UM valor que não seja NA.
Isso retornará as linhas que possuem pelo menos DOIS valor não-NA.
fonte
Para sua primeira pergunta, tenho um código com o qual me sinto à vontade para me livrar de todas as NAs. Obrigado por @Gregor para torná-lo mais simples.
Para a segunda pergunta, o código é apenas uma alternativa da solução anterior.
Observe que -5 é o número de colunas nos seus dados. Isso eliminará linhas com todos os NAs, uma vez que o rowSums soma até 5 e eles se tornam zeros após a subtração. Desta vez, como.logical é necessário.
fonte
Também podemos usar a função de subconjunto para isso.
Isso fornecerá apenas as linhas que não possuem NA em mmul e rnor
fonte
Eu sou um sintetizador :). Aqui eu combinei as respostas em uma função:
fonte
Assumindo
dat
como seu quadro de dados, a saída esperada pode ser alcançada usando1
rowSums
2)
lapply
fonte
Uma abordagem que é tanto geral e produz código bastante legível é usar a
filter
função e suas variantes no pacote dplyr (filter_all
,filter_at
,filter_if
):fonte
A função acima exclui todas as linhas do quadro de dados que possui 'NA' em qualquer coluna e retorna os dados resultantes. Se você deseja verificar vários valores como
NA
e?
alterar odart=c('NA')
parâmetro de função paradart=c('NA', '?')
fonte
Meu palpite é que isso poderia ser resolvido de maneira mais elegante desta maneira:
fonte
NA
. Eu acho que o que o OP quer é:df %>% filter_all(all_vars(!is.na(.)))