Добавление значений в один и тот же столбец в цикле for [R]

#r #dataframe #dplyr #data.table #plyr

#r #фрейм данных #dplyr #данные.таблица #plyr

Вопрос:

У меня есть фрейм данных с именем dt

 dt <- data.frame(a_check=c(NA,2,1,NA,NA),
                 b_check=c(NA,1,1,NA,1))
  

Я пытаюсь создать новый столбец с именем, error использующим ifelse условие, для сохранения всех ошибок, добавленных в этот столбец, с номером строки соответствующего NA

пример кода-

 for(i in 1:length(colnames(dt))){
  ## NA check for a_check column
  dt$error <- ifelse(is.na(dt[colnames(dt)[i]]),"Missing Value found in a_check on row number - ",NA)
  ## NA check for b_check column
  dt$error <- ifelse(is.na(dt[colnames(dt)[i]]),"Missing Value found in b_check on row number - ",NA)
}
  

Однако я хочу добавить сообщения об ошибках из a_check amp; b_check в тот же столбец.

Желаемый результат-

 > dt
  a_check b_check                                           error
1      NA      NA     Missing Value found in a_check on row number - 1 amp;  Missing Value found in b_check on row number - 1
2       2       1                                            <NA>
3       1       1                                            <NA>
4      NA      NA     Missing Value found in a_check on row number - 4 amp;  Missing Value found in b_check on row number - 4
5      NA       1     Missing Value found in a_check on row number - 5
  

** Примечание — я хочу paste номер строки и хочу добавлять сообщения об ошибках в тот же столбец в цикле for. Кроме того, у меня более 500 столбцов, именно по этой причине я использую цикл for.

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

1. Почему вы запускаете этот код в цикле for поверх строк?

2. обновлен код. спасибо, что указали!

Ответ №1:

Вы можете попробовать что-то вроде:

 library(data.table)
setDT(dt)[, error := if(any(is.na(.SD))) paste(c(.BY$rn, names(dt)[is.na(.SD)]), collapse=" "), 
    by=.(rn=seq_len(dt[,.N]))]
  

вывод:

    a_check b_check                   error
1:      NA      NA       1 a_check b_check
2:       2       1                    <NA>
3:       1       1                    <NA>
4:      NA      NA 4 a_check b_check error
5:      NA       1         5 a_check error
  

Ответ №2:

Если вы настроены на то, чтобы имена строк вставлялись в новый столбец, то использование for цикла и серии if инструкций может быть лучшим способом. Проблема, с которой вы пытаетесь использовать ifelse , заключается в том, что у вас есть более двух условий: оба error, a error, b error и no error.

Решение без использования ifelse

  x<-c()

for(i in 1:nrow(dt)){
  if(is.na(dt[i,"a_check"]) amp; is.na(dt[i,"b_check"])){
    x<- c(x,paste("Missing Value found in a_check amp; b_chekc", rownames(dt)[i]))
  }else if(is.na(dt[i,"a_check"])){
    x<- c(x,paste("Missing Value found in a_check", rownames(dt)[i]))
  }else if(is.na(dt[i,"b_check"])){
    x<- c(x,paste("Missing Value found in b_check", rownames(dt)[i]))
  }else{
   x<- c(x,NA)
  }
}

dt$error <- x
  

Обновить

Как вы указали, существует 500 столбцов, которые не будут работать, поэтому вы можете попробовать это

 # Create error message matrix
z<-sapply(colnames(dt), function(i){
ifelse(is.na(x[,i]),paste("Missing Value found in", i, sep =" "), NA)
  })
# Collapse matrix, no error will be an empty string  
error<-apply(z,1,function(i){
  paste(i[!is.na(i)], collapse = " amp; ")
})

dt$error <- error
  

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

1. У меня более 500 столбцов. Итак, я предполагаю, что вышеупомянутое решение для этого не сработает.

2. 500 столбцов? вы хотите выполнить поиск отсутствующих значений в каждом столбце?

3. Да, и добавить ошибки, соответствующие этой строке, для каждого столбца в поле ошибки. Вот почему я использую цикл for, в противном случае он довольно прост для 2 столбцов

4. Да, я думаю, что я бы попытался создать матрицу каждого из условий, а затем добавить их вместе. Я обновлю свой ответ.

5. Я получаю ошибку Error in [.data.frame (x, , i) : undefined columns selected при выполнении инструкции sapply.