Eu tenho um quadro de dados e algumas colunas têm NA
valores.
Como substituo esses NA
valores por zeros?
r
dataframe
na
missing-data
imputation
Renato Dinhani
fonte
fonte
Respostas:
Veja meu comentário na resposta @ gsk3. Um exemplo simples:
Não há necessidade de se inscrever
apply
. =)EDITAR
Você também deve dar uma olhada no
norm
pacote. Possui muitos recursos interessantes para a análise de dados ausentes. =)fonte
df[19:28][is.na(df[19:28])] <- 0
As opções hibridizadas do dplyr agora são cerca de 30% mais rápidas do que o subconjunto Base R reatribui. Em um dataponto de 100M, o dataframe
mutate_all(~replace(., is.na(.), 0))
é executado meio segundo mais rápido que ad[is.na(d)] <- 0
opção R básica . O que se deseja evitar especificamente é usar umifelse()
ou umif_else()
. (A análise completa de 600 ensaios durou mais de 4,5 horas, principalmente devido à inclusão dessas abordagens.) Consulte as análises de benchmark abaixo para obter os resultados completos.Se você está enfrentando grandes quadros de dados,
data.table
é a opção mais rápida de todas: 40% mais rápida que a abordagem padrão da Base R. Ele também modifica os dados, permitindo efetivamente trabalhar com quase o dobro dos dados de uma só vez.Um agrupamento de outras abordagens úteis de substituição ordenada
Localmente:
mutate_at(c(5:10), ~replace(., is.na(.), 0))
mutate_at(vars(var5:var10), ~replace(., is.na(.), 0))
mutate_at(vars(contains("1")), ~replace(., is.na(.), 0))
contains()
, tenteends_with()
,starts_with()
mutate_at(vars(matches("\\d{2}")), ~replace(., is.na(.), 0))
Condicionalmente:
(altere apenas um tipo e deixe outros tipos em paz.)
mutate_if(is.integer, ~replace(., is.na(.), 0))
mutate_if(is.numeric, ~replace(., is.na(.), 0))
mutate_if(is.character, ~replace(., is.na(.), 0))
A análise completa -
Atualizado para o dplyr 0.8.0: as funções usam
~
símbolos de formato purrr : substituindofuns()
argumentos obsoletos .Abordagens testadas:
O código para esta análise:
Resumo dos Resultados
Boxplot de Resultados
Gráfico de Dispersão com Código de Cores (com eixo y em uma escala de log)
Uma nota sobre os outros de alto desempenho
Quando os conjuntos de dados aumentam , os Tidyr 's
replace_na
historicamente se destacaram. Com a coleção atual de 100 milhões de pontos de dados para executar, ele executa quase exatamente tão bem quanto um Base R For Loop. Estou curioso para ver o que acontece com quadros de dados de tamanhos diferentes.Exemplos adicionais para o
mutate
esummarize
_at
e_all
variantes de função pode ser encontrada aqui: https://rdrr.io/cran/dplyr/man/summarise_all.html Além disso, eu encontrei manifestações votos e coleções de exemplos aqui: https: //blog.exploratory. io / dplyr-0-5-is-awesome-heres-why-be095fd4eb8aAtribuições e apreciações
Agradecimentos especiais a:
local()
e (com a ajuda do paciente de Frank também) o papel que a coerção silenciosa desempenha na aceleração de muitas dessas abordagens.coalesce()
função mais nova e atualizar a análise.data.table
funções bem o suficiente para finalmente incluí-las na programação.is.numeric()
realmente testa.(Obviamente, estenda a mão e dê a eles votos positivos também, se você achar essas abordagens úteis.)
Nota sobre o uso de Numéricos: Se você possui um conjunto de dados inteiro puro, todas as suas funções serão executadas mais rapidamente. Por favor, veja o trabalho de alexiz_laz para mais informações. IRL, não me lembro de encontrar um conjunto de dados contendo mais de 10 a 15% de números inteiros; portanto, estou executando esses testes em quadros de dados totalmente numéricos.
CPU utilizada de hardware de 3,9 GHz com 24 GB de RAM
fonte
df1[j][is.na(df1[j])] = 0
é errado, deve serdf1[[j]][is.na(df1[[j]])] = 0
forLp_Sbst
não parece ser uma maneira ninguém deve considerar aproximando-vsforLp_smplfSbst
coalesce()
opção e execute novamente o tempo todo. Obrigado pela atualização.Para um único vetor:
Para um data.frame, faça uma função fora das opções acima e depois
apply
nas colunas.Forneça um exemplo reproduzível da próxima vez, conforme detalhado aqui:
Como fazer um ótimo exemplo reprodutível de R?
fonte
is.na
é uma função genérica e possui métodos para objetos dedata.frame
classe. então este também funcionará emdata.frame
s!methods(is.na)
pela primeira vez, eu fiquei tipo, o que ?!? . Eu amo quando coisas assim acontecem! =)exemplo dplyr:
Nota: Isso funciona por coluna selecionada, se precisamos fazer isso para todas as colunas, consulte @reidjax 's resposta usando mutate_each .
fonte
Se estamos tentando substituir
NA
s ao exportar, por exemplo, ao gravar em csv, podemos usar:fonte
Sei que a pergunta já foi respondida, mas fazê-lo dessa maneira pode ser mais útil para alguns:
Defina esta função:
Agora, sempre que você precisar converter NA em um vetor para zero, você pode:
fonte
Com o
dplyr
0.5.0, você pode usar acoalesce
função que pode ser facilmente integrada ao%>%
pipeline fazendo issocoalesce(vec, 0)
. Isso substitui todas as NAs emvec
por 0:Digamos que temos um quadro de dados com
NA
s:fonte
Abordagem mais geral de utilizar
replace()
em matriz ou vector para substituirNA
a0
Por exemplo:
Essa também é uma alternativa ao uso
ifelse()
emdplyr
fonte
levels(A$x) <- append(levels(A$x), "notAnswered") A$x <- replace(A$x,which(is.na(A$x)),"notAnswered")
which
não é necessário aqui, você pode usarx1 <- replace(x,is.na(x),1)
.NA
a0
em apenas uma coluna específica em um grande quadro de dados e esta funçãoreplace()
trabalhou a forma mais eficaz e ao mesmo tempo o mais simples.Também é possível usar
tidyr::replace_na
.fonte
Outro exemplo usando o pacote imputeTS :
fonte
Se você deseja substituir NAs em variáveis fatoriais, isso pode ser útil:
Ele transforma um vetor de fator em um vetor numérico e adiciona outro nível de fator numérico artificial, que é então transformado novamente em um vetor de fator com um "nível de NA" extra de sua escolha.
fonte
Teria comentado na publicação de @ ianmunoz, mas não tenho reputação suficiente. Você pode combinar
dplyr
émutate_each
ereplace
para cuidar daNA
a0
substituição. Usando o dataframe da resposta de @ aL3xa ...Estamos usando a avaliação padrão (SE) aqui e é por isso que precisamos do sublinhado em "
funs_
." Também usamoslazyeval
'sinterp
/~
e as.
referências "tudo o que estamos trabalhando", ou seja, o quadro de dados. Agora existem zeros!fonte
Você pode usar
replace()
Por exemplo:
fonte
NA
s no seu vetor. É bom para vetores pequenos, como no seu exemplo.x1 <- replace(x,is.na(x),1)
funcionará sem listar explicitamente os valores do índice.Outra
dplyr
opção compatível com pipe com otidyr
métodoreplace_na
que funciona para várias colunas:Você pode restringir facilmente a, por exemplo, colunas numéricas:
fonte
A função dedicada (
nafill
/setnafill
) para esse fim está nadata.table
versão recentefonte
Essa função simples extraída do Datacamp pode ajudar:
Então
fonte
Uma maneira fácil de escrever é
if_na
dehablar
:que retorna:
fonte
Para substituir todas as NAs em um quadro de dados, você pode usar:
df %>% replace(is.na(.), 0)
fonte
se você deseja atribuir um novo nome após alterar os NAs em uma coluna específica, neste caso coluna V3, use também o seguinte:
fonte