У мене є кадр даних з деякими числовими стовпцями. Деякий рядок має значення 0, яке слід вважати нульовим у статистичному аналізі. Який найшвидший спосіб замінити всі значення 0 на NULL в R?
У мене є кадр даних з деякими числовими стовпцями. Деякий рядок має значення 0, яке слід вважати нульовим у статистичному аналізі. Який найшвидший спосіб замінити всі значення 0 на NULL в R?
Відповіді:
Заміна всіх нулів на NA:
df[df == 0] <- NA
Пояснення
1. Це не NULL
те, на що слід замінити нулі. Як говориться в ?'NULL'
,
NULL представляє нульовий об'єкт в R
яка унікальна і, я думаю, може розглядатися як найбільш неінформативний і порожній об’єкт. 1 Тоді це стає не так дивно
data.frame(x = c(1, NULL, 2))
# x
# 1 1
# 2 2
Тобто R не залишає місця для цього нульового об’єкта. 2 Тим часом, дивлячись, ?'NA'
ми бачимо це
NA - логічна константа довжини 1, яка містить показник пропущеного значення. NA може бути примушений до будь-якого іншого типу вектора, крім сировини.
Важливо, що NA
вона має довжину 1, так що R залишає для неї деякий простір. Наприклад,
data.frame(x = c(1, NA, 2))
# x
# 1 1
# 2 NA
# 3 2
Також структура кадру даних вимагає, щоб усі стовпці мали однакову кількість елементів, щоб не було «дірок» (тобто NULL
значень).
Тепер ви можете замінити нулі на NULL
кадр даних у сенсі повного видалення всіх рядків, що містять принаймні один нуль. При використанні, наприклад, var
, cov
, або cor
, що фактично еквівалентно першої заміни нулів з NA
і встановлюючи значення , use
як"complete.obs"
. Однак, як правило, це незадовільно, оскільки призводить до додаткової втрати інформації.
2. Замість запуску певного циклу, у розчині використовую df == 0
векторизацію. df == 0
повертає (спробуйте) матрицю такого ж розміру, як df
і записи TRUE
та FALSE
. Далі нам також дозволяється передавати цю матрицю підмножині [...]
(див. ?'['
). Нарешті, хоча результат df[df == 0]
ідеально інтуїтивний, це може здатися дивним, що df[df == 0] <- NA
дає бажаний ефект. Оператор присвоєння <-
дійсно не завжди настільки розумний і не працює таким чином з деякими іншими об'єктами, але це робить з кадрами даних; див ?'<-'
.
1 Порожній набір у теорії множин відчуває себе якось пов’язаним.
2 Ще одна схожість з теорією множин: порожній набір - це підмножина кожного набору, але ми не залишаємо для нього жодного місця.
Дозвольте припустити, що ваш data.frame - це сукупність різних типів даних, і не всі стовпці потрібно змінювати.
щоб змінити лише стовпці 12-18 (всього 21), просто зробіть це
df[, 12:18][df[, 12:18] == 0] <- NA
Альтернативний спосіб без [<-
функції:
Зразок кадру даних dat
(безсоромно скопійований з відповіді @ Chase):
dat
x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0
Нулі можуть бути замінені NA
на is.na<-
функції:
is.na(dat) <- !dat
dat
x y
1 NA 2
2 1 2
3 1 1
4 2 1
5 NA NA
Оскільки хтось запитав про версію Data.Table цього і тому, що дане рішення data.frame не працює з data.table, я пропоную рішення нижче.
В основному, використовуйте :=
оператор ->DT[x == 0, x := NA]
library("data.table")
status = as.data.table(occupationalStatus)
head(status, 10)
origin destination N
1: 1 1 50
2: 2 1 16
3: 3 1 12
4: 4 1 11
5: 5 1 2
6: 6 1 12
7: 7 1 0
8: 8 1 0
9: 1 2 19
10: 2 2 40
status[N == 0, N := NA]
head(status, 10)
origin destination N
1: 1 1 50
2: 2 1 16
3: 3 1 12
4: 4 1 11
5: 5 1 2
6: 6 1 12
7: 7 1 NA
8: 8 1 NA
9: 1 2 19
10: 2 2 40
Ви можете замінити 0
з NA
тільки в числових полях (тобто виключаючи такі речі , як фактори), але вона працює на основі стовпець за стовпцем:
col[col == 0 & is.numeric(col)] <- NA
За допомогою функції ви можете застосувати це до всього кадру даних:
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))
Хоча ви можете замінити на 1:5
кількість стовпців у вашому кадрі даних або на 1:ncol(df)
.
1:5
з 1:ncol(df)
в кінці. Я не хотів робити рівняння надто складним чи важким для читання.
1:5
на номери стовпців , які ви хочете змінилися, як 12:15
, але якщо ви хочете , щоб підтвердити , що він буде впливати тільки на стовпчики чисел , то просто загорнути другий рядок функції в , якщо заяву, як це: if (is.numeric(col)) { col[col == -1 & is.numeric(col)] <- NA }
.