[英]Change date format with format() in R
所以這是 R 中的一個基本算法,它打印出兩個日期之間的日期。
initial_date <- as.Date(toString((readline(prompt = "Enter a starting date in the format year-month-day:"))))
final_date <- as.Date(toString((readline(prompt = "Enter a final in the format year-month-day:"))))
dates <- seq(final_date, initial_date, by = "-1 day")
rev(dates[dates > initial_date & dates < final_date])
max.print = length(dates)
print(dates)
我想修改它,以便日期的格式為月-日-年:2008 年 11 月 27 日。所以我添加了“format(dates, format="%b %d %Y")”。
initial_date <- as.Date(toString((readline(prompt = "Enter a starting date in the format year-month-day:"))))
final_date <- as.Date(toString((readline(prompt = "Enter a final in the format year-month-day:"))))
dates <- seq(final_date, initial_date, by = "-1 day")
format(dates, format="%b %d %Y")
rev(dates[dates > initial_date & dates < final_date])
max.print = length(dates)
print(dates)
但這會繼續打印與之前代碼相同的輸出。 我如何解決它?
這里有幾點誤解:
format(dates, format="%b %d %Y")
可能會按照您希望的方式對其進行格式化,但它沒有被存儲,因此使用dates
的下一個命令正在使用調用前的對象format(..)
。 這以及大多數R 函數都是函數式的,這意味着它們的效果在存儲在對象中時實現:調用函數本身沒有副作用。 使用format
的“正確”方法是立即打印(見下文)或將其存儲到相同或另一個變量中。 雖然我不建議這樣做,但更實用的用途是
dates <- format(dates, format="%b %d %Y")
rev(dates[...])
同上:您需要立即使用它(如在print(rev(...))
,即立即函數調用的參數)或將其存儲在其他地方,例如
reversed_dates <- rev(dates[...])
在 R 中,日期(正確的Date
類)類似於數字,因此可以安全地進行連續數字比較,例如date1 < date2
和date2 >= date3
等。但是,如果您不小心比較了%Y-%m-%d
-字符串與另一個類似格式的字符串,那么它仍然可以工作。 它仍然有效,因為字符串是按字典順序比較的。 這意味着當比較字符串"2020-01-01"
和"2019-01-01"
,它會先比較"2"
和"2"
,它是平局; 與"0"
相同; 然后它將看到"2"
> "1"
,因此"2019-01-01"
在另一個之前。
即使作為字符串,這仍然有效,因為最重要的組件是年份,只要它們在字符串中排在第一位,相對順序( >
、 sort
、 order
)仍然有效。 如果日期是0
填充的整數,這將繼續工作。 這不工作,如果他們不是0
-padded,其中"2021-2-1" > "2021-11-1"
被報告為TRUE
; 這是因為它到達月份部分並將"2"
與"11"
的第一個"1"
進行比較,並且沒有看到下一個數字使"1"
大於"2"
。
當人們開始引入月份名稱時,這會出現同樣類型的錯誤,因為月份名稱(可能是任何語言?)不是按字典順序排列的(我不知道這是絕對真理,但肯定是在英語和也許許多/大多數西方語言中都是如此......我不會說其他語言的多語種)。 不幸的是,這意味着"2020-Apr-01" < "2020-Jan-01"
將再次為TRUE
。
我們將#3 與一般情況下,R 總是將Date
類對象打印為"%Y-%m-%d"
的事實相結合; 沒有(微不足道的)方法可以讓它將Date
類對象打印為您的"%b %d %Y"
而無需 (a) 將其轉換為字符串並失去正確的順序; 或 (b) 對其進行超級分類,使其在控制台上按照您想要的方式呈現,但它仍然是下面的數字。
至於(a),這是對圖中的報告和標簽所做的常見事情,我對此非常滿意。 我並不是要說服世界它應該始終將日期視為%Y-%m-%d
。 但是,我要說的是,在您實際渲染它之前將其保留為適當的Date
類對象要容易得多,然后在最后一秒對其進行format
。 為此,請執行所有過濾和排序,然后執行print(format(..))
,例如這樣。 我推薦這種方法。
dates <- seq(as.Date("2020-02-02"), as.Date("2020-02-06"), by = "day") dates <- rev(dates[ dates > as.Date("2020-02-03") ]) print(format(dates, format = "%b %d %Y")) # [1] "Feb 06 2020" "Feb 05 2020" "Feb 04 2020"
同樣,以上是我推薦的技術。
至於 (b),是的,你可以做到,但這種方法很脆弱,因為某些需要Date
類對象的函數不會立即認識到這些對象足夠接近以繼續工作,這是可行的; 或者他們將剝離我們分配的新類,此時它將采用"%Y-%m-%d"
格式。 您可以使用它,這要求您更改要個性化格式的每個Date
的類(請參閱# important
行)。 我建議不要這樣做。
format.myDATE <- function(x, ...) { # fashioned after format.Date xx <- format.Date(x, format = "%b %d %Y") names(xx) <- names(x) xx } print.myDATE <- function(x, max = NULL, ...) { # fashioned after print.Date if (is.null(max)) max <- getOption("max.print", 9999L) if (max < length(x)) { print(format.myDATE(x[seq_len(max)]), ...) cat(" [ reached 'max' / getOption(\\"max.print\\") -- omitted", length(x) - max, "entries ]\\n") } else if (length(x)) print(format.myDATE(x), ...) else cat(class(x)[1L], "of length 0\\n") invisible(x) } dates <- seq(as.Date("2020-02-02"), as.Date("2020-02-06"), by = "day") class(dates) <- c("myDATE", class(dates)) ## important! dates <- rev(dates[ dates > as.Date("2020-02-03") ]) print(dates) ## no need for format! # [1] "Feb 06 2020" "Feb 05 2020" "Feb 04 2020" ### and number-like operations still tend to work diff(dates) # Time differences in days # [1] -1 -1
同樣,我建議不要對您正在處理的數據執行此操作。 許多漂亮地打印表格和繪圖等的包可能會選擇覆蓋我們對格式的偏好,所以不能保證這會得到全面尊重。 這就是為什么我建議在使用 R 方式時“接受”它,而不管您的語言環境如何,並在打印/渲染之前立即根據您的審美偏好對其進行格式化。
另外幾個小點:
toString
,我認為它在這里對您沒有任何作用;max.print = ...
表明您認為這會改變其他任何東西; 大多數具有全局選項的 R 事物為此使用options(...)
,因此您需要在此 R 會話中使用options(max.print=length(dates))
全局設置它,或者使用print(dates, max = length(dates))
一次性限制print(dates, max = length(dates))
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.