2016-07-18 27 views
2

私は、指定された日付の週の最初の曜日を見つける関数を持っています。この特定の問題では、週は木曜日から始まります。停止日から桁への変換

この機能は、個々の日付でうまく機能します。

week_commencing <- function(date) { 
    weekday <- lubridate::wday(date) 
    if (weekday >= 5) { 
    return(date - lubridate::days(weekday) + lubridate::days(5)) 
    } else { 
    return(date - lubridate::days(weekday) - lubridate::days(2)) 
    } 
} 

ここでは、dplyrのパイプを使用したいと思います。そこで、Mapの列を受け入れるように変更しました。

week_commencing <- function(dates) { 
    Map(function(date) { 
    weekday <- lubridate::wday(date) 
    if (weekday >= 5) { 
     return(date - lubridate::days(weekday) + lubridate::days(5)) 
    } else { 
     return(date - lubridate::days(weekday) - lubridate::days(2)) 
    } 
    },dates) 
} 

私は機能が働いているが、私は桁の日付で終わるためにも日付にいくつかの奇妙な強制を適用していると思います。

> test <- data.frame(datetime=seq.Date(as.Date("2016-06-01"),as.Date("2016-06-10"), by='day')) 
> test 
    datetime 
1 2016-06-01 
2 2016-06-02 
3 2016-06-03 
4 2016-06-04 
5 2016-06-05 
6 2016-06-06 
7 2016-06-07 
8 2016-06-08 
9 2016-06-09 
10 2016-06-10 

> test %>% mutate(datetime=week_commencing(datetime)) 
    datetime 
1  16947 
2  16954 
3  16954 
4  16954 
5  16954 
6  16954 
7  16954 
8  16954 
9  16961 
10 16961 

正常な日付のオブジェクトで終了する方法についてのアイデアはありますか?マップは常に強制的に強制的に適用されますか?

答えて

3

なぜ、class属性がここにドロップされたのか分かりません(他の*適用機能を使用する場合も同様です)。 - 問題は、深いダウン、unlistはクラス落ちることのようだ:

> unlist(list(structure(1, class = 'foo'))) 
[1] 1 

をしかし、修正は十分に簡単です:最後にクラスを設定します。

さらに、Map(これはlistを返す)ではなく、vapplyを使用することをお勧めします。あなたはまた、機能上Vectorizeを使用することができ

week_commencing <- function(dates) { 
    wc <- function(date) { 
    weekday <- lubridate::wday(date) 
    if (weekday >= 5) { 
     return(date - lubridate::days(weekday) + lubridate::days(5)) 
    } else { 
     return(date - lubridate::days(weekday) - lubridate::days(2)) 
    } 
    } 

    structure(vapply(dates, wc, numeric(1)), class = 'Date') 
} 

が、それはまた、class属性を削除します。その後、我々はを残しています。

+0

おかげでたくさん!これは魅力のように機能します! 私はそのような構文 'class <--'(16947、 'Date')を見たことがありません... 名前はありますか?特に私がそれについて読むことができるように 'クラス< - '部分? – xav

+2

'\' class < - \ '(...)'の代わりに 'struct(vapply(dates、wc、numeric(1))、class =" Date ")'を使うこともできます。 – nrussell

+0

@xav 'class'の[replacement function](http://stackoverflow.com/q/11563154/1968)を呼び出します。私はこの構文を使用して、値を保持するために無駄な変数を作成しないようにしています(リンクされた答えの説明で変更したいのは、関数名に文字列を使用しないでください。 [代わりにバッククォート引用を使用する](http://stackoverflow.com/a/36229703/1968)、私の答えにあるように)。しかし、私はいつもここで同じことをするために 'structure'を使うことができます(私自身の答えで使っていますが)、nrussellの言い方を忘れてしまいます。 –

2

それとも、あなたはdplyr家族の中でそれを保つことができます:

week_commencing <- function(date) { 
    weekday <- lubridate::wday(date) 
    dplyr::if_else(weekday >= 5, 
       date - lubridate::days(weekday) + lubridate::days(5), 
       date - lubridate::days(weekday) - lubridate::days(2)) 
} 
+0

私はKonradの答えの柔軟性を好みますが、実際には900k行のデータセットでわずか数秒で実行されるため、現時点ではあなたのものを使用する必要があります。どうもありがとう! – xav

関連する問題