#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.