2014-02-05 143 views
9

我有以下數據框:格式日期年度/季度

Data <- data.frame(
    date = c("2001-01-01", "2001-02-01", "2001-03-01", "2001-04-01", "2001-05-01", "2001-06-01"), 
    qtr = c("NA", "NA","NA","NA","NA","NA") 
) 

我要填寫數據$ QTR與年/四 - F.E. 01/01(我需要這種格式!)。

我寫了一個函數:

fun <- function(x) { 
    if(x == "2001-01-01" | x == "2001-02-01" | x == "2001-03-01") y <- "01/01" 
    if(x == "2001-04-01" | x == "2001-05-01" | x == "2001-06-01") y <- "01/02" 
    return(y) 
} 
n$qtr <- sapply(n$date, fun) 

但它不工作。我總是得到錯誤信息:

Error in FUN(X[[1L]], ...) : Object 'y' not found 

爲什麼?

+0

你可能得到這個錯誤是因爲你的日期之一在'if'表達式中沒有匹配。所以'y'從來沒有被指定爲'樂趣'。 –

回答

19

您需要explicilty Vectorize你的函數:

fun_v <- Vectorize(fun, "x") 
fun_v(Data$date) 
#[1] "01/01" "01/01" "01/01" "01/02" "01/02" "01/02" 

然而,當涉及到更多或更少的標準任務(如日期時間的操作),總有已經上市的解決方案:

library(zoo) 
yq <- as.yearqtr(Data$date, format = "%Y-%m-%d") 
yq 
#[1] "2001 Q1" "2001 Q1" "2001 Q1" "2001 Q2" "2001 Q2" "2001 Q2" 

要轉換爲您的特定格式,請使用

format(yq, format = "%y/0%q") 
#[1] "01/01" "01/01" "01/01" "01/02" "01/02" "01/02" 
+0

謝謝。使用「format(z,format =」%y/0%q「)將是完美的,但是結果我得到」01/0q「等等 – feder80

+1

您可能忘記了'q'前面的'%'符號。 – tonytonov

+0

不,有一個% – feder80

8

使用基本功能:

Data$date <- as.Date(Data$date) 
Data$qtr <- paste(format(Data$date, "%y"), 
        sprintf("%02i", (as.POSIXlt(Data$date)$mon) %/% 3L + 1L), 
        sep="/") 

#   date qtr 
# 1 2001-01-01 01/01 
# 2 2001-02-01 01/01 
# 3 2001-03-01 01/01 
# 4 2001-04-01 01/02 
# 5 2001-05-01 01/02 
# 6 2001-06-01 01/02 
0

另一個(長)的方式使用if語句做的 是這樣的:

month <- as.numeric(format(date, format = "%m"))[1] 

if (month < 4) { 
    quarter <- paste(format(date, format = "%Y")[1], "Q1", sep="-") 
} else if (month > 3 & month < 7) { 
    quarter <- paste(format(date, format = "%Y")[1], "Q2", sep="-")    
} else if (month > 6 & month < 10) { 
    quarter <- paste(format(date, format = "%Y")[1], "Q3", sep="-") 
} else if (month > 9) { 
    quarter <- paste(format(date, format = "%Y")[1], "Q4", sep="-") 
} 

返回格式的字符串:

> quarter 
[1] "2001-Q1" 

然後,你可以使用循環擴展。

0
yq=function(x,prefix="%Y",combine="Q") paste0(ifelse(is.null(prefix),"",format(x,"%Y")),floor(as.numeric(format(x,"%m"))/3-1e-3)+1,sep=combine) 

這給

yq(as.Date("2013-04-30"),prefix="%y",combine="/0") 
> [1] "13/02" 
+0

隨着yearqtr你可以輕鬆地添加宿舍和執行其他操作,你也可以繪製yearqtr對象,並讓它正確出來,但沒有與字符字符串。 –

1

我做了一個返回具有季度它

不需要克隆氏病或動物園

爲你的榜樣任何格式回的靈活性在R中使用宿舍()和子()的類似格式:

Data$qtr <- paste(format(Data$date, "%y/"), 0, 
       sub("Q", "", quarters(Data$date)), sep = "") 

希望這有助於!

2

我一直喜歡lubridate包使用日期。超級光滑。 quarter函數查找季度(當然),然後將其與年份配對。

library(lubridate) 
Data <- Data %>% 
    mutate(qtr = paste0(substring(year(date),2,4),"/0",quarter(date))) 

如果你不熟悉的%>%第一線基本上說「利用數據幀稱爲data」,第二行寫着「突變(或增加)一個名爲qtr列」

相關問題