我有一个名为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和b_check的错误消息。
所需的输出-
> dt
a_check b_check error
1 NA NA Missing Value found in a_check on row number - 1 & 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 & 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循环的原因。
答案 0 :(得分:2)
您可以尝试以下操作:
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
答案 1 :(得分:1)
如果固定将行名粘贴到新列中,则使用for
循环和一系列if
语句可能是最好的方法。您尝试使用ifelse
时遇到的问题是您有两个以上的条件,分别是错误,错误,b错误和无错误。
不使用ifelse
x<-c()
for(i in 1:nrow(dt)){
if(is.na(dt[i,"a_check"]) & is.na(dt[i,"b_check"])){
x<- c(x,paste("Missing Value found in a_check & 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 = " & ")
})
dt$error <- error