Как проверить каждый элемент фрейма данных на наличие NA и распечатать их положение по отдельности (не в виде вектора)

#r

#r

Вопрос:

Я пытаюсь предоставить автоматический отчет о NAs в фрейме данных:

 #####create data frame

expl_data1 <- data.frame(var1 = c(NA, 7, 8, 9, 3), 
                         var2 = c(4, 1, NA, NA, 4), 
                         var3 = c(1, 4, 2, 9, 6), 
                         var4 = c("Hello", "I am not NA", NA, "I love R", NA)) 


#####check each element for NA
out<-apply(is.na(expl_data1), 2, which) 


####print a message with the NA's position

for (i in 1:length(out)){
  if (out[i] != "integer(0)"){
print(paste("Please remove missing values from ",names(out[i]), ", line ", out[i], sep= ""))
  }
}
 

Что печатается:

 > [1] "Please remove missing values from var1, line 1" 

> [1] "Please remove missing values from var2, line 3:4" 

> [1] "Please remove missing values from var4, line c(3, 5)"
 

Вывод в порядке, если в столбце есть только один NA. Но я недоволен выводом для нескольких NAS. Как я могу получить доступ и распечатать позиции по отдельности? Чего я хочу, так это

 > [1] "Please remove missing values from var1, line 1"
 
> [1] "Please remove missing values from var2, line 3" 

> [1] "Please remove missing values from var2, line 4" 

> [1] "Please remove missing values from var4, line 3"

> [1] "Please remove missing values from var4, line 5"
 

Ответ №1:

Вы можете использовать arr.ind from which для получения индекса строк и столбцов:

 na_pos <- which(is.na(expl_data1), arr.ind = TRUE)
paste("Please remove missing values from row", apply(na_pos, 1, paste, collapse = ", line "))
 

Комментарии:

1. Спасибо! Я попытался применить ваше решение следующим образом: for (i in 1:length(out)){ if(length(out[[i]])) { print(вставить(«Пожалуйста, удалите пропущенные значения из строки», применить (na_pos, 1, вставить, свернуть = «, строка»))) } } Но по какой-то причине он печатает текст три раза. Вы знаете, что здесь происходит?

2. Не нужно выполнять цикл. Я не использую out variable . Вы не используете i переменную в цикле, поэтому вы печатаете одно и то же на каждой итерации.

3. О, я понимаю. Вместо цикла «применить» применяет функцию which к каждой строке! Это тоже хороший ответ, спасибо.

Ответ №2:

Вот один из векторизованных способов сделать это :

 mat <- which(is.na(expl_data1), arr.ind = TRUE)
sprintf('Please remove missing values from %s, line%d', 
        names(expl_data1)[mat[, 2]], mat[, 1])

#[1] "Please remove missing values from var1, line1"
#[2] "Please remove missing values from var2, line3"
#[3] "Please remove missing values from var2, line4"
#[4] "Please remove missing values from var4, line3"
#[5] "Please remove missing values from var4, line5"
 

Чтобы исправить вашу попытку, вы можете использовать [[ вместо single [ . out[i] возвращает список, тогда out[[i]] как возвращает вектор. Вы можете проверить длину вывода, а не текст 'integer(0)' .

 for (i in 1:length(out)){
  if(length(out[[i]])) {
    print(paste("Please remove missing values from ",
          names(out[i]), ", line ", out[[i]], sep= ""))
  }
}

#[1] "Please remove missing values from var1, line 1"
#[1] "Please remove missing values from var2, line 3"
#[2] "Please remove missing values from var2, line 4"
#[1] "Please remove missing values from var4, line 3"
#[2] "Please remove missing values from var4, line 5"
 

Комментарии:

1. Спасибо. Это очень простое решение, и спасибо за предоставление более элегантной альтернативы экземплярам, где не было NAS.