2017-08-14 16 views
1

多くの人がこの問題を抱えているようですが、満足のいく回答は見つかりませんでした。あなたが私に気を遣うなら、何が起こっているのかを理解したいと思っています。dplyr :: mutateの関数:条件が長さ> 1の場合

私はそれを処理するための小さな機能を構築しているので、データフレームにさまざまな形式の日付があります。
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. 

フォーラムで読んだところ、私の現在の理解は、myDf $ myExampleのすべての要素を持つベクトルを、長さ> 1のベクトルを処理するために構築されていない関数に渡すことです。それが正しい場合、次のステップはそこから何をすべきかを理解することです。多くの人がifelseを使うのではなく、むしろifelseを使うことをお勧めしますが、これがどのように役立つのか分かりません。また、ifelseが入力と同じ形式のものを返すことも読んでいますが、その場合は私にとってはうまくいきません。

この質問に10000回回答していただきありがとうございます。

ニコラス

答えて

1

あなたはどこから行くべきか2つの選択肢があります。 1つはlapplyを使用して現在の関数をリストに適用することです。以下のように:

myDf$dateClean <- 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)) 
+1

変数に 'grepl(" - "、inputVector)'を指定して複数回書き直すのではなく、それを使用した方が読みやすいでしょう。おそらくもう少し効率的かもしれません。 – Frank

+1

チップをありがとう! - コードが更新されました –

+2

inputVectorが文字である場合には、inputVectorを最初に強制的に文字に変換すると便利です。 myDfでコードを試したところ、 "18-Mar-11"は大丈夫でしたが、 "42333"は1900年1月1日になりました。 –

関連する問題