一個月的天數我在P上的日期找出R中
date = as.Date("2011-02-23", "%Y-%m-%d")
是否有可能找出特定日期的月份的天數? (關於閏年)。在PHP它看起來與此類似(http://www.php.net/manual/en/function.date.php):
days = format(date, "%t")
但「%T」似乎有R.不同的含義是否有一個解決這個問題?
一個月的天數我在P上的日期找出R中
date = as.Date("2011-02-23", "%Y-%m-%d")
是否有可能找出特定日期的月份的天數? (關於閏年)。在PHP它看起來與此類似(http://www.php.net/manual/en/function.date.php):
days = format(date, "%t")
但「%T」似乎有R.不同的含義是否有一個解決這個問題?
您可以編寫簡單的函數來做到這一點:
numberOfDays <- function(date) {
m <- format(date, format="%m")
while (format(date, format="%m") == m) {
date <- date + 1
}
return(as.integer(format(date - 1, format="%d")))
}
調用爲:
> date = as.Date("2011-02-23", "%Y-%m-%d")
> numberOfDays(date)
[1] 28
> date # date is unchanged
[1] "2011-02-23"
這是因爲服用兩個日期之間的差異一樣簡單 - 因此使它成爲第一的月和次月:
R> difftime(as.Date("2011-06-01"), as.Date("2011-05-01"))
Time difference of 31 days
R> as.numeric(difftime(as.Date("2011-06-01"), as.Date("2011-05-01")))
[1] 31
R>
as.numeric()
將此轉換爲您可以使用的數字。
這基本上是德克的方法,但實際上放在一個函數中,以檢查下一個月是否也在下一年;並簡單地減去日期是一樣的使用difftime()
:
numberOfDays <- function(d){
temp <- unlist(strsplit(as.character(d),"-"))
begin <- as.Date(paste(temp[1],temp[2],"01",sep="-"))
if (temp[2] != "12"){
nextMonth <- as.character(as.integer(temp[2])+1)
end <- as.Date(paste(temp[1],nextMonth,"01",sep="-"))
return(as.integer(as.Date(end) - as.Date(begin)))
}
else{
nextYear <- as.character(as.integer(temp[1])+1)
end <- as.Date(paste(nextYear,"01","01",sep="-"))
return(as.integer(as.Date(end) - as.Date(begin)))
}
}
這裏有兩個辦法。兩種方法都是矢量化的,即輸入x
可以是一個單獨的"Date"
類日期或這樣的日期的向量。
1)據此,輸入日期,x
,成"yearmon"
對象,然後將其轉換回至最後的月份和第一個月和減去2加法1.
x <- Sys.Date() # use today as the test date
library(zoo)
ym <- as.yearmon(x)
as.Date(ym, frac = 1) - as.Date(ym) + 1
## Time difference of 30 days
或用於數字結果使用:
as.numeric(as.Date(ym, frac = 1) - as.Date(ym) + 1)
## [1] 30
1A)的變化將是:
as.Date(ym + 1/12) - as.Date(ym)
## Time difference of 30 days
或數字結果:
as.numeric(as.Date(ym + 1/12) - as.Date(ym))
## [1] 30
2)這是一個鹼溶液中。首先我們定義fom
,它輸入"Date"
向量並返回每個組件的月份的第一個。現在我們只考慮下個月的第一天和本月的第一天之間的差異。
fom <- function(x) as.Date(cut(x, "month"))
fom1 <- fom(x)
fom2 <- fom(fom1 + 32)
as.numeric(fom2 - fom1)
## [1] 30
+1我不知道''的''frac' arg as.Date()' - 這是在哪裏記錄的?當我做'as.Date'時它不會顯示出來。 – 2011-06-05 23:14:56
@Prasad,試試這個:'library(zoo); ?as.Date.yearmon'。 – 2011-06-06 00:51:00
這裏有一個簡單的辦法:在28:31
n
,發現導致有效日期的最大數量。在我的測試,這是快於任何的時間差爲基礎的方法至少4次:用一些其他的方法
ndays <- function(d) {
last_days <- 28:31
rev(last_days[which(!is.na(
as.Date(paste(substr(d, 1, 8),
last_days, sep = ''),
'%Y-%m-%d')))])[1]
}
> ndays('1999-03-10')
[1] 31
> ndays('1999-04-10')
[1] 30
> ndays('2000-02-10')
[1] 29
時序比較這裏建議:
> system.time(replicate(5000,
nd <- {
ym <- as.yearmon('2011-06-01');
as.numeric(as.Date(ym, frac = 1) - as.Date(ym) + 1)
}))
user system elapsed
16.634 1.807 18.238
> system.time(replicate(5000,
nd <- as.numeric(difftime(as.Date("2011-06-01"),
as.Date("2011-05-01")))))
user system elapsed
3.137 0.341 3.470
> system.time(replicate(5000, nd <- ndays('2011-06-01')))
user system elapsed
0.729 0.044 0.771
如果只在上述示例中的某個日期執行此操作,則速度無關緊要,而如果某人在多個日期執行此操作,那麼'yearmon'方法會更快,因爲它已經進行了矢量化處理。嘗試計時'd < - Sys.Date()+ 1:100; sapply(d,ndays)'與'd < - Sys.Date()+ 1:100; ym < - as.yearmon(d); as.numeric(as.Date(ym,frac = 1) - as.Date(ym)+ 1)'在我的系統中,後者速度提高了5倍。也就是說,速度在任何情況下通常都不重要。 'yearmon'解決方案的簡單性似乎是更重要的優勢。 – 2011-06-05 21:17:47
@ G.Grothendieck非常好的一點,我比較了時間,我同意你的看法。 – 2011-06-05 23:12:54
的Hmisc library有幾個有用的功能,這樣做的:
require(Hmisc)
monthDays(as.Date('2010-01-01'))
你可以通過這一年,或在默認情況下采取本年度:
days.in.month = function(month, year = NULL){
month = as.integer(month)
if (is.null(year))
year = as.numeric(format(Sys.Date(), '%Y'))
dt = as.Date(paste(year, month, '01', sep = '-'))
dates = seq(dt, by = 'month', length = 2)
as.numeric(difftime(dates[2], dates[1], units = 'days'))
}
這是另一種可能的功能,不需要安裝任何軟件包。您只需爲該功能提供一個日期對象。因爲這裏還有很多其他優秀的答案我用眼睛寫邁向相當簡單,(希望)容易閱讀:)
daysInMonth <- function(d = Sys.Date()){
m = substr((as.character(d)), 6, 7) # month number as string
y = as.numeric(substr((as.character(d)), 1, 4)) # year number as numeric
# Quick check for leap year
leap = 0
if ((y %% 4 == 0 & y %% 100 != 0) | y %% 400 == 0)
leap = 1
# Return the number of days in the month
return(switch(m,
'01' = 31,
'02' = 28 + leap, # adds 1 if leap year
'03' = 31,
'04' = 30,
'05' = 31,
'06' = 30,
'07' = 31,
'08' = 31,
'09' = 30,
'10' = 31,
'11' = 30,
'12' = 31))
}
如果你進行跳躍檢查'y %% 4 == 0&(y %% 100!= 0 | y %% 400 == 0)',那麼它將一直工作。 – Gregor 2014-07-29 18:11:27
非常好,謝謝你的提示。現在更新答案。 – 2014-07-29 18:17:27
非常好的答案。 – 2016-05-13 14:09:19
我提供一個又一個班輪沒有額外的軟件包需要:
NumberOfDays <- function(date)
return(as.numeric(format(as.Date(paste0(format(date,format="%Y"),formatC(ifelse(format(date,format="%m")=="12",0,as.numeric(format(date,format="%m")))+1,width=2,format="d",flag="0"),"01"),"%Y%m%d")-1,format="%d")))
> NumberOfDays(as.Date("2015-02-14","%Y-%m-%d"))
[1] 28
> system.time(NumberOfDays(as.Date("2015-02-14","%Y-%m-%d")))
user system elapsed
0.0010000000 0.0000000000 0.0009999999
您應該使用您自己的首選項的格式爲此函數提供Date對象。
在另一種方式來獲得的日子可能是:
# Any date
Today <- Sys.Date()
# Get Month and Year
Month <- format(Today,"%m")
Year <- format(Today,"%Y")
# get first date for the next month and then subtract 1
Days <- format(
as.Date(
paste0("01/",(as.numeric(Month)%%12)+1,"/",Year)
,"%d/%m/%Y")-1,"%d")
「Lubridate」軟件包所需的功能「days_in_month」關於leapyears。
你舉的例子:
> date = as.Date("2011-02-23", "%Y-%m-%d")
> days_in_month(date)
Feb
28
閏年(2016):
> date_leap = as.Date("2016-02-23", "%Y-%m-%d")
> days_in_month(date_leap)
Feb
29
,我遲到了,但這個功能更好,並支持矢量:
month_days <- function(mon) {
# input as class "Date"
require(lubridate)
day(mon) <- 1
given <- mon
month(given) <- month(given) + 1
as.numeric(given - mon)
}
> Ymd<-"201602"
> lastDate<-format(seq(as.POSIXct(sprintf("%s%s",substr(Ymd,1,6),"01"),format="%Y%m%d"),length=2,by="1 month")-1,"%Y%m%d")[2]
> cat(as.integer(lastDate)%%100)
29
# Other Output
> lastDate
[1] "20160229"
> cat(substr(lastDate,7,8))
29
只有代碼答案不能爲問題提供良好的解決方案。請嘗試解釋你所做的事情並添加信息。 – creyD 2018-02-01 13:44:49
這是另一種替代溶膠使用動物園的yearmon。 這是一個快速實用程序。
require(zoo)
days_in_month <- function(d) {
rigor_days_in_month <- function(d) {
get_day <- function(x) as.numeric(format(x,"%d"))
m <- zoo::as.yearmon(d)
get_day(as.Date(m, frac = 1))
}
mm <- as.numeric(format(d,"%m")) # get_month
ifelse(mm %in% c(1,3,5,7,8,10,12), 31,
ifelse(mm != 2, 30,
rigor_days_in_month(d)))
}
如果你願意,你可以解開get_day()使它成爲一行代碼。
如果通過的日期是本月的第一天,我不確定這是否有效。 – joran 2011-06-05 14:09:49
不適用於載體......請查看我的方法 – Zafar 2017-09-16 01:24:00