【问题标题】:If function in dplyr::mutate : the condition has length > 1如果 dplyr::mutate 中的函数:条件的长度 > 1
【发布时间】:2023-04-10 21:14:02
【问题描述】:

很多人似乎有这个问题,但我无法找到令人满意的答案。如果你放纵我,我想确保了解发生了什么

我在数据框中有各种格式的日期(也是一个常见问题),所以我构建了一个小函数来为我处理它:

dateHandler <- function(inputString){
  if(grepl("-",inputString)==T){
    lubridate::dmy(inputString, tz="GMT")
  }else{
    as.POSIXct(as.numeric(inputString)*60*60*24, origin="1899-12-30", tz="GMT")
  }
}

在一个元素上使用它时效果很好:

myExample <-c("18-Mar-11","42433")

> dateHandler(myExample[1])
[1] "2011-03-18 GMT"
> dateHandler(myExample[2])
[1] "2016-03-04 GMT"

但是在整列上使用它时它不起作用:

myDf <- as.data.frame(myExample)
> myDf <- myDf %>% 
+   dplyr::mutate(dateClean=dateHandler(myExample))
Warning messages:
1: In if (grepl("-", inputString) == T) { :
  the condition has length > 1 and only the first element will be used
2:  1 failed to parse. 

从论坛上的阅读来看,我目前的理解是,R 将包含 myDf$myExample 的所有元素的向量传递给函数,该函数不是为处理长度 >1 的向量而构建的。如果这是正确的,下一步就是了解从那里做什么。许多人建议使用 ifelse 而不是 if 但我不明白这对我有什么帮助。我还读到 ifelse 返回与其输入格式相同的内容,在这种情况下这对我不起作用。

提前感谢您第 10000 次回答这个问题。

尼古拉斯

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    你有两个选择从那里去哪里。一种是使用lapply 将当前函数应用于列表。如:

    myDf$dateClean &lt;- lapply(myDf$myExample, function(x) dateHandler(x))

    另一种选择是构建一个向量化函数,该函数旨在将向量而不是单个数据点作为输入。这是一个简单的例子:

    dateHandlerVectorized <- function(inputVector){
    
      output <- rep(as.POSIXct("1/1/11"), length(inputVector))
      UseLuridate <- grepl("-", inputVector)
      output[UseLuridate] <- lubridate::dmy(inputVector[UseLuridate], tz="GMT")
      output[!UseLuridate] <- as.POSIXct(as.numeric(inputVector[!UseLuridate])*60*60*24, origin="1899-12-30", tz="GMT")
      output
    
    }
    
    myDf <- myDf %>% dplyr::mutate(dateClean=dateHandlerVectorized(myDf$myExample))
    

    【讨论】:

    • 在我看来,如果您将grepl("-", inputVector) 分配给一个变量并使用它而不是多次重写,它会更容易阅读。可能效率也更高。
    • 首先将 inputVector 强制转换为字符也可能很有用,以防它是一个因素。当我在 myDf 上尝试代码时,“18-Mar-11”结果没问题,但“42333”变成了 1900 年 1 月 1 日。
    猜你喜欢
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 2021-04-23
    相关资源
    最近更新 更多