Mam ramkę danych, a niektóre kolumny mają NA
wartości.
Jak zastąpić te NA
wartości zerami?
r
dataframe
na
missing-data
imputation
Renato Dinhani
źródło
źródło
Odpowiedzi:
Zobacz mój komentarz w odpowiedzi na @ gsk3. Prosty przykład:
Nie ma potrzeby aplikowania
apply
. =)EDYTOWAĆ
Powinieneś także spojrzeć na
norm
pakiet. Ma wiele fajnych funkcji do analizy brakujących danych. =)źródło
df[19:28][is.na(df[19:28])] <- 0
Hybrydyzowane opcje dplyr są teraz około 30% szybsze niż ponowne przypisanie podzbioru Base R. Na 100 M ramce danych punktu danych
mutate_all(~replace(., is.na(.), 0))
działa o pół sekundy szybciej niż podstawowad[is.na(d)] <- 0
opcja R. To, czego konkretnie chce się uniknąć, to używanieifelse()
lubif_else()
. (Pełna analiza 600 prób trwała ponad 4,5 godziny, głównie z powodu uwzględnienia tych podejść). Pełne wyniki można znaleźć poniżej w analizie porównawczej.Jeśli zmagasz się z ogromnymi ramkami danych,
data.table
to najszybsza opcja ze wszystkich: 40% szybsza niż standardowe podejście Base R. Modyfikuje również dane w miejscu, umożliwiając efektywną pracę z prawie dwukrotnie większą ilością danych naraz.Grupowanie innych pomocnych podejść zastępczych typu Tidyverse
Lokalnie:
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()
, spróbujends_with()
,starts_with()
mutate_at(vars(matches("\\d{2}")), ~replace(., is.na(.), 0))
Warunkowo:
(zmień tylko jeden typ i zostaw inne typy w spokoju).
mutate_if(is.integer, ~replace(., is.na(.), 0))
mutate_if(is.numeric, ~replace(., is.na(.), 0))
mutate_if(is.character, ~replace(., is.na(.), 0))
Pełna analiza -
Zaktualizowano dla dplyr 0.8.0: funkcje używają
~
symboli formatu purrr : zastępując przestarzałefuns()
argumenty.Testowane podejścia:
Kod do tej analizy:
Podsumowanie rezultatów
Wykres wyników
Kolorowy wykres rozproszenia prób (z osią y na skali logarytmicznej)
Uwaga na temat innych najlepszych wykonawców
Gdy zbiory danych stają się większe, Tidyr „” s
replace_na
historycznie wyciągnięta w przód. Przy obecnym zbiorze 100 milionów punktów danych do przejścia, działa on prawie tak samo dobrze, jak Base R For Loop. Jestem ciekawy, co dzieje się w przypadku ramek danych o różnych rozmiarach.Dodatkowe przykłady wariantów
mutate
isummarize
_at
i_all
można znaleźć tutaj: https://rdrr.io/cran/dplyr/man/summarise_all.html Dodatkowo znalazłem pomocne demonstracje i kolekcje przykładów tutaj: https: //blog.exploratory. io / dplyr-0-5-is-awesome-heres-dlaczego-be095fd4eb8aAtrybucje i podziękowania
Specjalne podziękowania dla:
local()
oraz (z pomocą pacjenta Franka) roli, jaką odgrywa cichy przymus w przyspieszaniu wielu z tych podejść.coalesce()
funkcję i zaktualizować analizę.data.table
funkcje wystarczająco dobrze, by w końcu włączyć je do składu.is.numeric()
naprawdę sprawdza.(Oczywiście, proszę sięgnij do nich i oddaj im głosowanie, jeśli uznasz to za przydatne).
Uwaga na temat używania przeze mnie Numerics: Jeśli masz zestaw danych o całkowitej liczbie całkowitej, wszystkie twoje funkcje będą działały szybciej. Więcej informacji znajdziesz w pracy alexiz_laz . IRL, nie mogę sobie przypomnieć, że napotkałem zestaw danych zawierający więcej niż 10-15% liczb całkowitych, więc przeprowadzam te testy na w pełni numerycznych ramkach danych.
Używany sprzęt Procesor 3,9 GHz z 24 GB pamięci RAM
źródło
df1[j][is.na(df1[j])] = 0
jest źle, powinien byćdf1[[j]][is.na(df1[[j]])] = 0
forLp_Sbst
nie wydaje się, aby ktokolwiek powinien rozważyć zbliżenie się do niegoforLp_smplfSbst
coalesce()
opcję i ciągle uruchamiam ponownie. Dziękujemy za aktualizację.Dla pojedynczego wektora:
W przypadku data.frame utwórz funkcję z powyższego, a następnie
apply
do kolumn.Następnym razem podaj powtarzalny przykład, jak wyszczególniono tutaj:
Jak zrobić doskonały przykład odtwarzalnego R?
źródło
is.na
jest funkcją ogólną i ma metody dla obiektówdata.frame
klasy. więc ten będzie również działał nadata.frame
s!methods(is.na)
pierwszy raz pobiegłem , byłem jak co? . Uwielbiam, gdy takie rzeczy się zdarzają! =)przykład dplyr:
Uwaga: To działa na wybranej kolumnie, jeśli trzeba to zrobić dla wszystkich kolumn, patrz @reidjax „s odpowiedź za pomocą mutate_each .
źródło
Jeśli próbujemy zastąpić
NA
s podczas eksportowania, na przykład podczas pisania do csv, możemy użyć:źródło
Wiem, że na pytanie już udzielono odpowiedzi, ale zrobienie tego w ten sposób może być bardziej przydatne dla niektórych:
Zdefiniuj tę funkcję:
Teraz, gdy trzeba przekonwertować NA w wektorze na zero, możesz:
źródło
W wersji
dplyr
0.5.0 można korzystać zcoalesce
funkcji, które można łatwo zintegrować z%>%
rurociągiemcoalesce(vec, 0)
. Zastępuje wszystkie NA wvec
0:Powiedzmy, że mamy ramkę danych zs
NA
:źródło
Bardziej ogólne podejście
replace()
do zastępowania w macierzy lub wektorzeNA
do0
Na przykład:
Jest to również alternatywa dla używania
ifelse()
wdplyr
źródło
levels(A$x) <- append(levels(A$x), "notAnswered") A$x <- replace(A$x,which(is.na(A$x)),"notAnswered")
which
nie jest tutaj potrzebny, możesz użyćx1 <- replace(x,is.na(x),1)
.NA
je0
tylko w jednej konkretnej kolumnie w dużej ramce danych, a ta funkcjareplace()
działała najskuteczniej, a jednocześnie najprościej.Możliwe jest również użycie
tidyr::replace_na
.źródło
Kolejny przykład z wykorzystaniem pakietu imputeTS :
źródło
Jeśli chcesz zastąpić NA zmiennymi czynnikowymi, może to być przydatne:
Przekształca wektor czynnikowy w wektor liczbowy i dodaje kolejny sztuczny poziom liczbowy czynnika, który jest następnie przekształcany z powrotem w wektor czynnikowy z jednym wybranym dodatkowym „poziomem NA”.
źródło
Skomentowałbym post @ ianmunoz, ale nie mam wystarczającej reputacji. Można łączyć
dplyr
„smutate_each
ireplace
do dbać oNA
do0
zastąpienia. Korzystanie z ramki danych z odpowiedzi @ aL3xa ...Używamy tutaj standardowej oceny (SE), dlatego potrzebujemy podkreślenia na „
funs_
.” Używamy równieżlazyeval
„interp
/ /”~
i.
„wszystkiego, z czym pracujemy”, tj. Ramki danych. Teraz są zera!źródło
Możesz użyć
replace()
Na przykład:
źródło
NA
s w wektorze. Jest odpowiedni dla małych wektorów, jak w twoim przykładzie.x1 <- replace(x,is.na(x),1)
będzie działać bez jawnego wyświetlania wartości indeksu.Inna
dplyr
opcja kompatybilna z potokiem ztidyr
metodą,replace_na
która działa dla kilku kolumn:Możesz łatwo ograniczyć się do np. Kolumn numerycznych:
źródło
Dedykowana funkcja (
nafill
/setnafill
) do tego celu znajduje się w najnowszejdata.table
wersjiźródło
Ta prosta funkcja wyodrębniona z Datacamp może pomóc:
Następnie
źródło
Łatwym sposobem, aby ją napisać to ze
if_na
odhablar
:który zwraca:
źródło
Aby zastąpić wszystkie NA w ramce danych, możesz użyć:
df %>% replace(is.na(.), 0)
źródło
jeśli chcesz przypisać nową nazwę po zmianie NA w określonej kolumnie w tym przypadku w kolumnie V3, użyj tego możesz również zrobić w ten sposób
źródło