Измените пустые ячейки на "NA"
Здесь ссылка моих данных.
Моя цель - назначить "NA" всем пустым ячейкам независимо от категориальных или числовых значений. Я использую na.strings = "". Но он не назначает NA всем пустым ячейкам.
## reading the data
dat <- read.csv("data2.csv")
head(dat)
mon hr acc alc sex spd axles door reg cond1 drug1
1 8 21 No Control TRUE F 0 2 2 Physical Impairment (Eyes, Ear, Limb) A
2 7 20 No Control FALSE M 900 2 2 Inattentive D
3 3 9 No Control FALSE F 100 2 2 2004 Normal D
4 1 15 No Control FALSE M 0 2 2 Physical Impairment (Eyes, Ear, Limb) D
5 4 21 No Control FALSE 25 NA NA D
6 4 20 No Control NA F 30 2 4 Drinking Alcohol - Impaired D
inj1 PED_STATE st rac1
1 Fatal <NA> F <NA>
2 Moderate <NA> F <NA>
3 Moderate <NA> M <NA>
4 Complaint <NA> M <NA>
5 Complaint <NA> F <NA>
6 Moderate <NA> M <NA>
## using na.strings
dat2 <- read.csv("data2.csv", header=T, na.strings="")
head(dat2)
mon hr acc alc sex spd axles door reg cond1 drug1
1 8 21 No Control TRUE F 0 2 2 <NA> Physical Impairment (Eyes, Ear, Limb) A
2 7 20 No Control FALSE M 900 2 2 <NA> Inattentive D
3 3 9 No Control FALSE F 100 2 2 2004 Normal D
4 1 15 No Control FALSE M 0 2 2 <NA> Physical Impairment (Eyes, Ear, Limb) D
5 4 21 No Control FALSE 25 NA NA <NA> <NA> D
6 4 20 No Control NA F 30 2 4 <NA> Drinking Alcohol - Impaired D
inj1 PED_STATE st rac1
1 Fatal NA F NA
2 Moderate NA F NA
3 Moderate NA M NA
4 Complaint NA M NA
5 Complaint NA F NA
6 Moderate NA M NA
Ответы
Ответ 1
Я предполагаю, что вы говорите о столбце "стол" в строке 5. Это может быть так, что в файле data2.csv ячейка содержит пробел и, следовательно, не считается пустым через R.
Кроме того, я заметил, что в столбцах строк 5 "оси" и "дверь" исходные значения, считанные из data2.csv, являются строками "NA". Вы, вероятно, захотите относиться к ним как к nststrings. Для этого
dat2 <- read.csv("data2.csv", header=T, na.strings=c("","NA"))
EDIT:
Я загрузил ваши данные2.csv. Да, в строке 5 столбцов "секс" есть пробел. Итак, вы хотите
na.strings=c(""," ","NA")
Ответ 2
Вы можете использовать gsub для замены нескольких мутаций пустого, например "" или пробела, для NA:
data= data.frame(cats=c('', ' ', 'meow'), dogs=c("woof", " ", NA))
apply(data, 2, function(x) gsub("^$|^ $", NA, x))
Ответ 3
Более удобное для глаз решение с использованием dplyr
require(dplyr)
## fake blank cells
iris[1,1]=""
## define a helper function
empty_as_na <- function(x){
if("factor" %in% class(x)) x <- as.character(x) ## since ifelse wont work with factors
ifelse(as.character(x)!="", x, NA)
}
## transform all columns
iris %>% mutate_each(funs(empty_as_na))
Чтобы применить исправление только к подмножеству столбцов, вы можете указать интересующие столбцы, используя синтаксис сопоставления столбцов dplyr. Пример: mutate_each(funs(empty_as_na), matches("Width"), Species)
Если ваша таблица содержит даты, вы должны использовать более безопасную версию ifelse
Ответ 4
Недавно я столкнулся с подобными проблемами. Это то, что сработало для меня, если переменная является числовой, тогда достаточно простого df$Var[df$Var == ""] <- "NA"
. Но если переменная является фактором, тогда вам нужно сначала преобразовать ее в символ, а затем заменить ячейки ""
на нужное значение и преобразовать обратно в коэффициент. Так что, например, ваша переменная Sex, я предполагаю, что это будет фактором, и если вы хотите заменить пустую ячейку, я бы сделал следующее:
df$Var <- as.character(df$Var)
df$Var[df$Var==""] <- "NA"
df$Var <- as.factor(df$Var)
Ответ 5
Это должно сделать свое дело
dat <- dat %>% mutate_all(na_if,"")
Ответ 6
Моя функция учитывает фактор, вектор символов и потенциальные атрибуты, если вы используете гавань или сторонний пакет для чтения внешних файлов. Также это позволяет сопоставлять различные определенные пользователем строки. Чтобы преобразовать все столбцы, просто используйте lappy: df[] = lapply(df, blank2na, na.strings=c('','NA','na','N/A','n/a','NaN','nan'))
Смотрите больше комментариев:
#' Replaces blank-ish elements of a factor or character vector to NA
#' @description Replaces blank-ish elements of a factor or character vector to NA
#' @param x a vector of factor or character or any type
#' @param na.strings case sensitive strings that will be coverted to NA. The function will do a trimws(x,'both') before conversion. If NULL, do only trimws, no conversion to NA.
#' @return Returns a vector trimws (always for factor, character) and NA converted (if matching na.strings). Attributes will also be kept ('label','labels', 'value.labels').
#' @seealso \code{\link{ez.nan2na}}
#' @export
blank2na = function(x,na.strings=c('','.','NA','na','N/A','n/a','NaN','nan')) {
if (is.factor(x)) {
lab = attr(x, 'label', exact = T)
labs1 <- attr(x, 'labels', exact = T)
labs2 <- attr(x, 'value.labels', exact = T)
# trimws will convert factor to character
x = trimws(x,'both')
if (! is.null(lab)) lab = trimws(lab,'both')
if (! is.null(labs1)) labs1 = trimws(labs1,'both')
if (! is.null(labs2)) labs2 = trimws(labs2,'both')
if (!is.null(na.strings)) {
# convert to NA
x[x %in% na.strings] = NA
# also remember to remove na.strings from value labels
labs1 = labs1[! labs1 %in% na.strings]
labs2 = labs2[! labs2 %in% na.strings]
}
# the levels will be reset here
x = factor(x)
if (! is.null(lab)) attr(x, 'label') <- lab
if (! is.null(labs1)) attr(x, 'labels') <- labs1
if (! is.null(labs2)) attr(x, 'value.labels') <- labs2
} else if (is.character(x)) {
lab = attr(x, 'label', exact = T)
labs1 <- attr(x, 'labels', exact = T)
labs2 <- attr(x, 'value.labels', exact = T)
# trimws will convert factor to character
x = trimws(x,'both')
if (! is.null(lab)) lab = trimws(lab,'both')
if (! is.null(labs1)) labs1 = trimws(labs1,'both')
if (! is.null(labs2)) labs2 = trimws(labs2,'both')
if (!is.null(na.strings)) {
# convert to NA
x[x %in% na.strings] = NA
# also remember to remove na.strings from value labels
labs1 = labs1[! labs1 %in% na.strings]
labs2 = labs2[! labs2 %in% na.strings]
}
if (! is.null(lab)) attr(x, 'label') <- lab
if (! is.null(labs1)) attr(x, 'labels') <- labs1
if (! is.null(labs2)) attr(x, 'value.labels') <- labs2
} else {
x = x
}
return(x)
}
Ответ 7
Несмотря на то, что многие из вышеперечисленных опций работают хорошо, я считаю, что приведение нецелевых переменных к chr
проблематично Использование ifelse
и grepl
в lapply
устраняет этот lapply
эффект (в ограниченном тестировании). Использование регулярного выражения grepl
в grepl
:
set.seed(42)
x1 <- sample(c("a","b"," ", "a a", NA), 10, TRUE)
x2 <- sample(c(rnorm(length(x1),0, 1), NA), length(x1), TRUE)
df <- data.frame(x1, x2, stringsAsFactors = FALSE)
Проблема приведения к классу персонажей:
df2 <- lapply(df, function(x) gsub("^$|^ $", NA, x))
lapply(df2, class)
$ x1
[1] "персонаж"
$ x2 [1] "персонаж"
Разрешение с использованием ifelse:
df3 <- lapply(df, function(x) ifelse(grepl("^$|^ $", x)==TRUE, NA, x))
lapply(df3, class)
$ x1
[1] "персонаж"
$ x2 [1] "числовой"
Ответ 8
Вы также можете использовать mutate_at
в dplyr
dat <- dat %>%
mutate_at(vars(colnames(.)),
.funs = funs(ifelse(.=="", NA, as.character(.))))
Выберите отдельные столбцы для изменения:
dat <- dat %>%
mutate_at(vars(colnames(.)[names(.) %in% c("Age","Gender")]),
.funs = funs(ifelse(.=="", NA, as.character(.))))
Начиная с (dplyr 0.8.0 выше) способ написания этого документа изменился. До этого был funs()
в .funs (funs(name = f(.))
. Вместо funs
теперь мы используем list (list(name = ~f(.)))
Обратите внимание, что существует также гораздо более простой способ перечислить имена столбцов! (как имя столбца, так и индекс столбца работают)
dat <- dat %>%
mutate_at(.vars = c("Age","Gender"),
.funs = list(~ifelse(.=="", NA, as.character(.))))
Ответ 9
Не могли бы вы просто использовать
dat <- read.csv("data2.csv",na.strings=" ",header=TRUE)
должен преобразовать все пробелы в NA, поскольку данные считываются в
не забудьте поставить пробел между цитатами
Ответ 10
Для тех, кто интересуется решением с использованием метода data.table, вот один:
dat2[, lapply(.SD, gsub, pattern = "^$|^ $", replacement = NA),]
просто пройдитесь по каждой строке и примените функцию gsub()
к каждой ячейке, соответствующей шаблону "^$|^ $"
, чтобы заменить их значение на NA
.
Было бы неплохо, если бы кто-нибудь смог сделать бенчмаркинг, чтобы увидеть, какой подход самый быстрый.
Ответ 11
Вызовите пакет dplyr
, установив из cran
в т
library(dplyr)
(file)$(colname)<-sub("-",NA,file$colname)
Он преобразует все пустые ячейки в определенном столбце как NA
Если столбец содержит "-", "", 0, как это, измените его в коде в соответствии с типом пустой ячейки
Например, если я получаю пустую ячейку, например "" вместо "-", то используйте этот код:
(file)$(colname)<-sub("", NA, file$colname)