在R中计算星期五或星期一的月数

时间:2013-11-11 18:27:38

标签: r lubridate

我想要一个计算每月特定天数的函数。

,即2013年11月 - > 5周五..而13年12月将返回4周五..

是否有一个优雅的功能会返回这个?

library(lubridate)

num_days <- function(date){
x <- as.Date(date)  
start = floor_date(x, "month")
count = days_in_month(x)

d = wday(start) 
sol = ifelse(d > 4, 5, 4) #estimate that is the first day of the month is after Thu or Fri then the week will have 5 Fridays
sol
}

num_days("2013-08-01")
num_days(today())

最好的办法是什么?

3 个答案:

答案 0 :(得分:11)

1)此处d是输入,Date类对象,例如d <- Sys.Date()。结果给出了包含d的年/月的星期五数。将5替换为1以获取星期一的数量:

first <- as.Date(cut(d, "month"))
last <- as.Date(cut(first + 31, "month")) - 1
sum(format(seq(first, last, "day"), "%w") == 5)

2)或者用以下行替换最后一行。在这里,第一个术语是从下个月的第一个月或之后的大纪元到下个星期五的星期五的数量,第二个术语是在{{的第一个或之后的大纪元到下个星期五的星期五的数量。 1月}。同样,我们将所有5个替换为1,以获得星期一的计数。

d

第二种解决方案稍长(尽管它具有相同的行数),但它具有矢量化的优点,即ceiling(as.numeric(last + 1 - 5 + 4) / 7) - ceiling(as.numeric(first - 5 + 4) / 7) 可以是日期的矢量。

更新:添加了第二个解决方案。

答案 1 :(得分:2)

有很多方法可以做到这一点。这是一个:

countFridays <- function(y, m) { 
    fr <- as.Date(paste(y, m, "01", sep="-")) 
    to <- fr + 31       
    dt <- seq(fr, to, by="1 day")      
    df <- data.frame(date=dt, mon=as.POSIXlt(dt)$mon, wday=as.POSIXlt(dt)$wday)  
    df <- subset(df, df$wday==5 & df$mon==df[1,"mon"])         
    return(nrow(df))     
}

它创造了第一个月,以及接下来几个月的一天。

然后创建月份索引的数据框(在0到11范围内,但我们仅将其用于比较)和工作日。

然后我们将a)分配到a)同一个月和b)星期五。那是你的结果集,而且 我们返回行数作为你的anwser。

请注意,这仅使用基本R代码。

答案 2 :(得分:2)

不使用lubridate -

#arguments to pass to function:
whichweekday <- 5
whichmonth <- 11
whichyear <- 2013

#function code:    
firstday <- as.Date(paste('01',whichmonth,whichyear,sep="-"),'%d-%m-%Y')
lastday <- if(whichmonth == 12) { '31-12-2013' } else {seq(as.Date(firstday,'%d-%m-%Y'), length=2, by="1 month")[2]-1}
sum(
  strftime(
seq.Date(
  from = firstday,
  to = lastday,
  by = "day"),
'%w'
) == whichweekday)