将值附加到for循环中的同一列[R]

问题描述 投票:0回答:2

我有一个名为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列,这就是我用于循环的原因。

r dataframe dplyr data.table plyr
2个回答
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
投票

如果您已修复将rownames粘贴到新列中,那么使用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
© www.soinside.com 2019 - 2024. All rights reserved.