[英]Stop Map from converting dates to digits
I have a function that find the first day of the week for a given date. 我有一个功能,可以找到给定日期的一周的第一天。 In this particular problem, weeks do start on Thursday.
在这个特殊的问题上,星期几从星期四开始。
The function works well for individual dates. 该功能适用于各个日期。
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))
}
}
Now, I would like to use it a pipe with dplyr
. 现在,我想将它与
dplyr
一起使用。 So I modified it to accept columns with Map
. 所以我修改了它以接受
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)
}
I think the function is working, but is also applying some weird coercion to the dates because I end up with digit 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
Any ideas on how to end up with normal date object? 关于如何以正常日期对象结束的任何想法? Is Map always applying coercion?
地图是否总是施加强制性?
I don't know why the class
attribute is dropped here (the same happens when using other *apply functions). 我不知道为什么将
class
属性放在这里(使用其他* apply函数时也会发生同样的情况)。 — The issue, deep down, seems to be that unlist
drops classes: —从
unlist
,问题似乎在于unlist
删除类:
> unlist(list(structure(1, class = 'foo')))
[1] 1
But the fix is straightforward enough: set the class at the end. 但是解决方法很简单:将类放在最后。
Furthermore, I'd suggest not using Map
(which returns a list
) but rather vapply
. 此外,我建议不要使用
Map
(它返回一个list
),而是使用vapply
。 Then we're left with: 然后我们剩下:
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')
}
You could also use Vectorize
on the function, but that also removes the class
attribute. 您也可以在该函数上使用
Vectorize
,但这也会删除class
属性。
Or, you could keep it in the dplyr
family: 或者,您可以将其保留在
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))
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.