Следующая функция заменяет все значения NA
и '?'
на наиболее частые значения столбца.Тогда это всего лишь вопрос lapply
его передачи в data.frame.
mostFreq <- function(x, na = '?'){
i <- is.na(x) | x %in% na
tbl <- table(x[!i])
x[i] <- names(tbl)[which.max(tbl)]
if(is.factor(x)) x <- droplevels(x)
x
}
# Before
as.list(dat1[1:20, 1:3])
#$V1
# [1] "1" "?" "2" "?" "2" NA "?" "?" "2" "?" "?" "?" NA NA
#[15] NA NA "?" "2" "2" "2"
#
#$V2
# [1] "1" "3" "2" "3" "1" "2" "1" "2" "3" "1" "2" "1" "?" NA
#[15] "?" "3" "1" NA "?" "1"
#
#$V3
# [1] "?" "1" "?" "3" "1" NA NA "3" "1" "1" "1" "2" NA NA
#[15] NA NA "?" "?" NA "2"
# After
lapply(dat1[1:20, 1:3], mostFreq)
#$V1
# [1] "1" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2"
#[15] "2" "2" "2" "2" "2" "2"
#
#$V2
# [1] "1" "3" "2" "3" "1" "2" "1" "2" "3" "1" "2" "1" "1" "1"
#[15] "1" "3" "1" "1" "1" "1"
#
#$V3
# [1] "1" "1" "1" "3" "1" "1" "1" "3" "1" "1" "1" "2" "1" "1"
#[15] "1" "1" "1" "1" "1" "2"
и изменения всего фрейма данных.
dat1[] <- lapply(dat1, mostFreq)
И приведение к классу factor
:
dat1[] <- lapply(dat1, factor)
Редактировать.
Вышеприведенную функцию можно упростить, если вы начнете читать настройку данных na.strings = '?'
.
dat1 <- fread(<URI>, na.strings = '?', <other args>)
Затем используйте функцию ниже, где был исходный mostFreq
.
mostFreq2 <- function(x){
tbl <- table(x, useNA = "no")
x[is.na(x)] <- names(tbl)[which.max(tbl)]
x
}
Тестовые данные.
Поскольку вы не опубликовали примерный набор данных, я будусоздайте такой же, как описано в вопросе.
set.seed(1234) # Make the results reproducible
n <- 300
x <- replicate(6, sample(c(NA, '?', 1:2), n, TRUE))
y <- replicate(6, sample(c(NA, '?', 1:3), n, TRUE))
dat1 <- cbind.data.frame(x, y, stringsAsFactors = FALSE)
dat1 <- dat1[, sample(ncol(dat1))]
names(dat1) <- paste0('V', 1:12)
str(dat1)