У меня есть фреймворк с несколькими числовыми столбцами. Некоторая строка имеет значение 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 может быть приведен к любому другому векторному типу, кроме raw.
Важно отметить, 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 }
.