Mam ramkę danych z kilkoma kolumnami numerycznymi. Niektóre wiersze mają wartość 0, które w analizie statystycznej należy uznać za zerowe. Jaki jest najszybszy sposób zamiany wszystkich wartości 0 na NULL w R?
Nie sądzę, abyś chciał / mógł zastąpić wartościami NULL, ale NA służy temu celowi w języku R.
Chase,
Odpowiedzi:
243
Zamiana wszystkich zer na NA:
df[df ==0]<-NA
Wyjaśnienie
1. To nie jest to, NULLczym powinieneś chcieć zastępować zera. Jak mówi ?'NULL',
NULL reprezentuje pusty obiekt w języku R
który jest wyjątkowy i, jak sądzę, może być postrzegany jako obiekt najbardziej pozbawiony informacji i pusty. 1 W takim razie nie jest to zaskakujące
data.frame(x = c(1,NULL,2))# x# 1 1# 2 2
Oznacza to, że R nie rezerwuje żadnego miejsca dla tego pustego obiektu. 2 Tymczasem, patrząc na ?'NA'to, widzimy
NA jest stałą logiczną o długości 1, która zawiera wskaźnik brakującej wartości. NA można wymusić na dowolnym innym typie wektora oprócz surowego.
Co ważne, NAma długość 1, więc R rezerwuje na nią trochę miejsca. Na przykład,
data.frame(x = c(1,NA,2))# x# 1 1# 2 NA# 3 2
Ponadto struktura ramki danych wymaga, aby wszystkie kolumny miały taką samą liczbę elementów, aby nie było „dziur” (tj. NULLWartości).
Teraz możesz zastąpić zera NULLw ramce danych w sensie całkowitego usunięcia wszystkich wierszy zawierających co najmniej jedno zero. W przypadku korzystania np var, covalbo cor, że jest właściwie równoznaczne z pierwszą wymianą zer NAi ustawienie wartości usejak "complete.obs". Zwykle jest to jednak niezadowalające, ponieważ prowadzi do dodatkowej utraty informacji.
2. Zamiast uruchamiać jakąś pętlę, w rozwiązaniu df == 0stosuję wektoryzację. df == 0zwraca (spróbuj) macierz o takim samym rozmiarze jak df, z wpisami TRUEi FALSE. Ponadto możemy również przekazać tę macierz do podzbioru [...](zobacz ?'['). Wreszcie, chociaż wynik df[df == 0]jest całkowicie intuicyjny, może wydawać się dziwne, że df[df == 0] <- NAdaje pożądany efekt. Operator przypisania <-rzeczywiście nie zawsze jest tak inteligentny i nie działa w ten sposób z niektórymi innymi obiektami, ale robi to z ramkami danych; zobacz ?'<-'.
1 Pusty zbiór w teorii mnogości wydaje się w jakiś sposób powiązany. 2 Kolejne podobieństwo do teorii mnogości: zbiór pusty jest podzbiorem każdego zbioru, ale nie rezerwujemy dla niego miejsca.
Jaka byłaby równoważna składnia dla obiektu data.table?
itpetersen,
6
Widzę, że otrzymaliście dużo głosów, ale nie sądzę, aby to odpowiednio obejmowało skrajne przypadki kolumn nienumerycznych z wartościami „0”, które nie miały być ustawione na <NA>.
IRTFM
33
Załóżmy, że plik data.frame jest mieszanką różnych typów danych i nie wszystkie kolumny wymagają modyfikacji.
aby zmodyfikować tylko kolumny od 12 do 18 (z łącznie 21), po prostu zrób to
#Sample data
set.seed(1)
dat <- data.frame(x = sample(0:2,5,TRUE), y = sample(0:2,5,TRUE))#-----
x y102212311421500#replace zeros with NA
dat[dat==0]<-NA#-----
x y1NA22123114215NANA
Lub for (j in names(DT)); set(DT,which(DT[[j]] == 0),j,NA). Zobacz tutaj, aby uzyskać bardziej szczegółowe omówienie używania data.table do znajdowania i zastępowania wartości.
JWilliman
4
Można wymienić 0ze NAtylko w polach liczbowych (czyli z wyłączeniem rzeczy jak czynników), ale działa na podstawie kolumna po kolumnie:
col[col ==0& is.numeric(col)]<-NA
Za pomocą funkcji możesz zastosować to do całej ramki danych:
changetoNA <-function(colnum,df){
col <- df[,colnum]if(is.numeric(col)){#edit: verifying column is numeric
col[col ==-1& is.numeric(col)]<-NA}return(col)}
df <- data.frame(sapply(1:5, changetoNA, df))
Chociaż możesz zamienić na 1:5liczbę kolumn w ramce danych lub na 1:ncol(df).
Nie jestem pewien, czy to poprawne rozwiązanie. A co z kolumnami 6 i więcej. Zostaną pocięte.
userJT
Dlatego zaproponował zastąpienie 1:5ze 1:ncol(df)na końcu. Nie chciałem, aby równanie było zbyt skomplikowane lub trudne do odczytania.
Alium Britt
ale co jeśli w kolumnach 6 i 7 - typ danych to char i nie należy go zastępować. W moim problemie potrzebuję wymiany tylko w kolumnach od 12 do 15, ale cały df ma 21 kolumn (wielu w ogóle nie wolno dotykać).
userJT
Na ramce danych można po prostu zmienić 1:5numerom kolumnę, którą chcesz zmienić, jak 12:15, ale jeśli chciał potwierdzić, że będzie to miało wpływ tylko kolumn numerycznych potem po prostu owinąć drugą linię funkcji w if, tak: if (is.numeric(col)) { col[col == -1 & is.numeric(col)] <- NA }.
Alium Britt,
0
W przypadku, gdy ktoś przybywa tutaj przez Google i szuka czegoś przeciwnego (tj. Jak zamienić wszystkie NA w data.frame na 0), odpowiedź brzmi
Odpowiedzi:
Zamiana wszystkich zer na NA:
Wyjaśnienie
1. To nie jest to,
NULL
czym powinieneś chcieć zastępować zera. Jak mówi?'NULL'
,który jest wyjątkowy i, jak sądzę, może być postrzegany jako obiekt najbardziej pozbawiony informacji i pusty. 1 W takim razie nie jest to zaskakujące
Oznacza to, że R nie rezerwuje żadnego miejsca dla tego pustego obiektu. 2 Tymczasem, patrząc na
?'NA'
to, widzimyCo ważne,
NA
ma długość 1, więc R rezerwuje na nią trochę miejsca. Na przykład,Ponadto struktura ramki danych wymaga, aby wszystkie kolumny miały taką samą liczbę elementów, aby nie było „dziur” (tj.
NULL
Wartości).Teraz możesz zastąpić zera
NULL
w ramce danych w sensie całkowitego usunięcia wszystkich wierszy zawierających co najmniej jedno zero. W przypadku korzystania npvar
,cov
albocor
, że jest właściwie równoznaczne z pierwszą wymianą zerNA
i ustawienie wartościuse
jak"complete.obs"
. Zwykle jest to jednak niezadowalające, ponieważ prowadzi do dodatkowej utraty informacji.2. Zamiast uruchamiać jakąś pętlę, w rozwiązaniu
df == 0
stosuję wektoryzację.df == 0
zwraca (spróbuj) macierz o takim samym rozmiarze jakdf
, z wpisamiTRUE
iFALSE
. Ponadto możemy również przekazać tę macierz do podzbioru[...]
(zobacz?'['
). Wreszcie, chociaż wynikdf[df == 0]
jest całkowicie intuicyjny, może wydawać się dziwne, żedf[df == 0] <- NA
daje pożądany efekt. Operator przypisania<-
rzeczywiście nie zawsze jest tak inteligentny i nie działa w ten sposób z niektórymi innymi obiektami, ale robi to z ramkami danych; zobacz?'<-'
.1 Pusty zbiór w teorii mnogości wydaje się w jakiś sposób powiązany.
2 Kolejne podobieństwo do teorii mnogości: zbiór pusty jest podzbiorem każdego zbioru, ale nie rezerwujemy dla niego miejsca.
źródło
Załóżmy, że plik data.frame jest mieszanką różnych typów danych i nie wszystkie kolumny wymagają modyfikacji.
aby zmodyfikować tylko kolumny od 12 do 18 (z łącznie 21), po prostu zrób to
źródło
Alternatywny sposób bez
[<-
funkcji:Przykładowa ramka danych
dat
(bezwstydnie skopiowana z odpowiedzi @ Chase):Zera może być zastąpiona
NA
przezis.na<-
funkcję:źródło
dplyr::na_if()
jest opcją:źródło
źródło
Ponieważ ktoś poprosił o wersję Data.Table tego, a podane rozwiązanie data.frame nie współpracuje z data.table, poniżej przedstawiam rozwiązanie.
Zasadniczo użyj
:=
operatora ->DT[x == 0, x := NA]
źródło
for (j in names(DT)); set(DT,which(DT[[j]] == 0),j,NA)
. Zobacz tutaj, aby uzyskać bardziej szczegółowe omówienie używania data.table do znajdowania i zastępowania wartości.Można wymienić
0
zeNA
tylko w polach liczbowych (czyli z wyłączeniem rzeczy jak czynników), ale działa na podstawie kolumna po kolumnie:Za pomocą funkcji możesz zastosować to do całej ramki danych:
Chociaż możesz zamienić na
1:5
liczbę kolumn w ramce danych lub na1:ncol(df)
.źródło
1:5
ze1:ncol(df)
na końcu. Nie chciałem, aby równanie było zbyt skomplikowane lub trudne do odczytania.1:5
numerom kolumnę, którą chcesz zmienić, jak12:15
, ale jeśli chciał potwierdzić, że będzie to miało wpływ tylko kolumn numerycznych potem po prostu owinąć drugą linię funkcji w if, tak:if (is.numeric(col)) { col[col == -1 & is.numeric(col)] <- NA }
.W przypadku, gdy ktoś przybywa tutaj przez Google i szuka czegoś przeciwnego (tj. Jak zamienić wszystkie NA w data.frame na 0), odpowiedź brzmi
LUB
Używanie dplyr / tidyverse
źródło