我想將字符串(例如「2005M09」,「2005M10」等)轉換爲R中的日期。我想要顯示01/09/2005而不是2005M09,01/10/2005而不是2005M10等將字符串轉換爲R中的日期(2005M09轉換爲01/09/2005)
有沒有一個簡單的解決方案來實現這一目標?
預先感謝您!
我想將字符串(例如「2005M09」,「2005M10」等)轉換爲R中的日期。我想要顯示01/09/2005而不是2005M09,01/10/2005而不是2005M10等將字符串轉換爲R中的日期(2005M09轉換爲01/09/2005)
有沒有一個簡單的解決方案來實現這一目標?
預先感謝您!
使用strsplit
將字符串拆分爲「M」。然後將結果年份&與當天的「01」一起粘貼。最後,使用as.Date
。向量化,使用sapply
:
> foo <- c("2005M09","2005M10")
> as.Date(sapply(strsplit(foo,"M"),
function(xx)paste(xx[1],"-",xx[2],"-01",sep="")))
[1] "2005-09-01" "2005-10-01"
如果你喜歡在你的問題的輸出格式,這樣做:
> bar <- as.Date(sapply(strsplit(foo,"M"),
function(xx)paste(xx[1],"-",xx[2],"-01",sep="")))
> format(bar,format="%d/%m/%Y")
[1] "01/09/2005" "01/10/2005"
看看在lubridate包,它有很多功能,用於處理日期。一種選擇是貼上類似「D01」,以每個日期,然後使用ymd
功能:
> ymd(paste0(c('2005M09','2014M05'), 'D01'))
[1] "2005-09-01 UTC" "2014-05-01 UTC"
或拆分的一年,像斯蒂芬月份提出並使用lubridate功能使用那些年月:
> tmp <- strsplit(c('2005M09','2014M05'), 'M')
> dates <- rep(today(), length(tmp))
> year(dates) <- as.numeric(sapply(tmp, `[`, 1))
> month(dates) <- as.numeric(sapply(tmp, `[`, 2))
> day(dates) <- 1
> dates
[1] "2005-09-01" "2014-05-01"
您可以使用as.Date()
轉換爲日期,並打印它就像你想要的。看看?strptime
看看如何構造format
參數的字符串。
txt <- c("2005M09", "2005M10")
(d <- as.Date(paste0(txt, "01"), format="%YM%m%d"))
#[1] "2005-09-01" "2005-10-01"
format(d, "%d/%m/%Y")
#[1] "01/09/2005" "01/10/2005"
你也可以使用substr
創建一個字符串這是「容易」轉換爲日期。我認爲這兩種解決方案會比使用strsplit
和sapply
d <- as.Date(paste0(substr(txt, 1, 4), substr(txt, 6, 7), "01"), format="%Y%m%d")
其實快了不少,忘記轉換爲日期,你可以簡單地substr
出你想要什麼,但是你想它粘貼在一起(如果這是所有你想做的事...存儲爲Date
小號有日期可能使其他事情變得更容易。)
> paste("01", substr(txt, 6, 7), substr(txt, 1, 4), sep="/")
[1] "01/09/2005" "01/10/2005"
或者,這裏有一個正則表達式的解決方案
> sub("(\\d{4})M(\\d{2})", "01/\\2/\\1", txt)
[1] "01/09/2005" "01/10/2005"
如果速度是一個問題,這裏是一個標杆
gsee1 <- function(txt) {
format(as.Date(paste0(txt, "01"), format="%YM%m%d"), "%d/%m/%Y")
}
gsee2 <- function(txt) {
format(as.Date(paste0(substr(txt, 1, 4), substr(txt, 6, 7), "01"),
format="%Y%m%d"), "%d/%m/%Y")
}
gsee3 <- function(txt) {
paste("01", substr(txt, 6, 7), substr(txt, 1, 4), sep="/")
}
gsee4 <- function(txt) {
sub("(\\d{4})M(\\d{2})", "01/\\2/\\1", txt, perl=TRUE)
}
gsnow <- function(txt) {
tmp <- strsplit(txt, 'M')
dates <- rep(today(), length(tmp))
year(dates) <- as.numeric(sapply(tmp, `[`, 1))
month(dates) <- as.numeric(sapply(tmp, `[`, 2))
day(dates) <- 1
format(dates, "%d/%m/%Y")
}
stephan <- function(txt) {
format(as.Date(sapply(strsplit(txt,"M"),
function(xx)paste(xx[1],"-",xx[2],"-01",sep=""))),
format="%d/%m/%Y")
}
identical(gsee1(txt), gsee2(txt))
#[1] TRUE
identical(gsee1(txt), gsee3(txt))
#[1] TRUE
identical(gsee1(txt), gsee4(txt))
#[1] TRUE
identical(gsee1(txt), gsnow(txt))
#[1] TRUE
identical(gsee1(txt), stephan(txt))
#[1] TRUE
結果:
library(rbenchmark)
# Create a bigger input vector
txt <- c(outer(1900:2100, sprintf("%02d", 1:12), paste, sep="M"))
benchmark(gsee1(txt),
gsee2(txt),
gsee3(txt),
gsee4(txt),
gsnow(txt),
stephan(txt))
# test replications elapsed relative user.self sys.self user.child sys.child
# 1 gsee1(txt) 100 0.413 3.896 0.412 0.000 0 0
# 2 gsee2(txt) 100 0.470 4.434 0.468 0.000 0 0
# 3 gsee3(txt) 100 0.140 1.321 0.140 0.000 0 0
# 4 gsee4(txt) 100 0.106 1.000 0.104 0.000 0 0
# 5 gsnow(txt) 100 4.407 41.575 4.400 0.004 0 0
# 6 stephan(txt) 100 2.526 23.830 2.420 0.100 0 0
什麼你嘗試了嗎? – Bonifacio2