将mutate_at与嵌套的ifelse一起使用

时间:2018-01-04 23:28:16

标签: r dplyr mutate

这将使得值不在columnA,NA中给定条件(使用%>%)。

mutate_at(vars(-columnA), funs(((function(x) {
if (is.logical(x))
  return(x)
else if (!is.na(as.numeric(x)))
  return(as.numeric(x))
else
  return(NA)
})(.))))

如何使用mutate_at和嵌套ifelse实现相同的结果?

例如,这不会产生相同的结果:

mutate_at(vars(-columnA),funs(ifelse(is.logical(.),.,
ifelse(!is.na(as.numeric(.)),as.numeric(.),NA))))

更新(2018-1-5)

问题的目的是令人困惑,部分原因是由于我对传递给函数的内容存在误解。

这是我打算写的:

mutate_at(vars(-columnA), funs(((function(x) {
  for(i in 1:length(x))
  {
    if(!is.na(as.numeric(x[i])) && !is.logical(x[i])) 
    {
      x[i] <- as.numeric(x[i]);
    }
    else if(!is.na(x[i]))
    {
      x[i] <- NA
    }
  }
  return(x)    
})(.))))

这是一个更好的解决方案:

mutate_at(vars(-columnA), function(x) {
  if(is.logical(x)) 
      return(x)

  return(as.numeric(x))
})
在这种情况下,ifelse可能不合适,因为它返回的值与条件的形状相同,即1个逻辑元素。在这种情况下,is.logical(。),条件的结果长度为1,因此返回值将是传递给函数的列的第一个元素。

更新(2018-1-6)

使用ifelse,这将返回包含逻辑值或NA的列,否则将以.numeric的形式应用于列。

mutate_at(vars(-columnA),funs(
ifelse(. == TRUE | . == FALSE | is.na(.),.,as.numeric(.))))

1 个答案:

答案 0 :(得分:2)

主要问题是

else if (!is.na(as.numeric(x)))
     return(as.numeric(x)) 

if/else适用于vector length 1。如果应用此功能的length的{​​{1}}大于1,则最好使用vector/column。在上文中,ifelse返回长度大于1的逻辑!is.na(as.numeric(x))(假设数据集中的行数大于1)。使它工作的方法是用vector包裹(取决于我们需要的)

all/any

数据

f1 <- function(x) {
    if (is.logical(x))
         return(x)
      else if (all(!is.na(as.numeric(x))))
         return(as.numeric(x))
          else
       return(x) #change if needed
}

df1 %>%
    mutate_all(f1)