亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

R如何用小數秒格式化POSIXct

R如何用小數秒格式化POSIXct

手掌心 2019-08-27 13:39:23
R如何用小數秒格式化POSIXct我認為R錯誤地使用小數秒格式化POSIXct類型。我通過R-bugs作為增強請求提交了這個,并且“我們認為當前的行為是正確的 - 刪除了bug”。雖然我非常感謝他們已經完成并將繼續做的工作,但我想讓其他人對這個特定問題采取行動,并且可能就如何更有效地提出要點提出建議。這是一個例子: > tt <- as.POSIXct('2011-10-11 07:49:36.3')  > strftime(tt,'%Y-%m-%d %H:%M:%OS1')  [1] "2011-10-11 07:49:36.2"也就是說,tt被創建為POSIXct時間,小數部分.3秒。當使用一個十進制數字打印時,顯示的值為.2。我使用毫秒級精度的時間戳工作很多,這讓我很煩惱,因為時間通常比實際值低一個等級。以下是發生的事情:POSIXct是自紀元以來的浮點秒數。精確處理所有整數值,但在base-2浮點中,與.3最接近的值略小于.3。strftime()格式的所述行為%OSn是向下舍入到請求的小數位數,因此顯示的結果為.2。對于其他小數部分,浮點值略高于輸入的值,顯示屏給出預期結果: > tt <- as.POSIXct('2011-10-11 07:49:36.4')  > strftime(tt,'%Y-%m-%d %H:%M:%OS1')  [1] "2011-10-11 07:49:36.4"開發人員的論點是,對于時間類型,我們應該總是向下舍入到請求的精度。例如,如果時間是11:59:59.8,那么用格式打印它%H:%M應該給出“11:59”而不是“12:00”,并且%H:%M:%S 應該給出“11:59:59”而不是“12:00:00”。我同意這個整數秒和格式標志%S,但我認為對于為秒的小數部分設計的格式標志,行為應該是不同的。我希望看到%OSn使用舍入到最近的行為,即使是n = 0同時%S使用循環下來,從而使打印11:59:59.8與格式%H:%M:%OS0會給“12:00:00”。這不會影響整數秒的任何事情,因為它們總是精確地表示,但它會更自然地處理小數秒的舍入誤差。這就是如何處理小數部分的打印,例如C,因為整數轉換向下舍入: double x = 9.97;  printf("%d\n",(int) x);   //  9  printf("%.0f\n",x);       //  10  printf("%.1f\n",x);       //  10.0  printf("%.2f\n",x);       //  9.97我做了一個關于如何在其他語言和環境中處理小數秒的快速調查,并且似乎確實沒有達成共識。大多數構造設計為整數秒,而小數部分是事后想法。在我看來,在這種情況下,R開發人員做出的選擇并非完全不合理,但實際上并不是最好的選擇,并且與其他地方用于顯示浮點數的約定不一致。人們的想法是什么?R行為是否正確?這是你自己設計它的方式嗎?
查看完整描述

2 回答

?
慕尼黑8549860

TA貢獻1818條經驗 獲得超11個贊


一個潛在的問題是POSIXct表示不如POSIXlt表示精確,并且POSIXct表示在格式化之前轉換為POSIXlt表示。下面我們看到如果我們的字符串直接轉換為POSIXlt表示,它輸出正確。


> as.POSIXct('2011-10-11 07:49:36.3')

[1] "2011-10-11 07:49:36.2 CDT"

> as.POSIXlt('2011-10-11 07:49:36.3')

[1] "2011-10-11 07:49:36.3"

我們還可以通過查看兩種格式的二進制表示與0.3的通常表示之間的差異來看到。


> t1 <- as.POSIXct('2011-10-11 07:49:36.3')

> as.numeric(t1 - round(unclass(t1))) - 0.3

[1] -4.768372e-08


> t2 <- as.POSIXlt('2011-10-11 07:49:36.3')

> as.numeric(t2$sec - round(unclass(t2$sec))) - 0.3

[1] -2.831069e-15

有趣的是,看起來兩個表示實際上都比0.3的通常表示要小,但是第二個表示要么足夠接近,要么截斷的方式與我想象的不同。鑒于此,我不會擔心浮點表示困難; 它們可能仍然會發生,但如果我們小心使用哪種表示方式,它們有望最小化。


羅伯特對圓形輸出的渴望只是輸出問題,可以通過多種方式解決。我的建議是這樣的:


myformat.POSIXct <- function(x, digits=0) {

  x2 <- round(unclass(x), digits)

  attributes(x2) <- attributes(x)

  x <- as.POSIXlt(x2)

  x$sec <- round(x$sec, digits)

  format.POSIXlt(x, paste("%Y-%m-%d %H:%M:%OS",digits,sep=""))

}

這從POSIXct輸入開始,并首先輪到所需的數字; 然后轉換為POSIXlt并再次舍入。第一輪舍入確保當我們處于分鐘/小時/天邊界時所有單元都適當增加; 轉換為更精確的表示后的第二輪四舍五入。


> options(digits.secs=1)

> t1 <- as.POSIXct('2011-10-11 07:49:36.3')

> format(t1)

[1] "2011-10-11 07:49:36.2"

> myformat.POSIXct(t1,1)

[1] "2011-10-11 07:49:36.3"


> t2 <- as.POSIXct('2011-10-11 23:59:59.999')

> format(t2)

[1] "2011-10-11 23:59:59.9"

> myformat.POSIXct(t2,0)

[1] "2011-10-12 00:00:00"

> myformat.POSIXct(t2,1)

[1] "2011-10-12 00:00:00.0"

最后一個:你知道標準允許最多兩個閏秒嗎?


> as.POSIXlt('2011-10-11 23:59:60.9')

[1] "2011-10-11 23:59:60.9"

好的,還有一件事。由于OP提交的錯誤,該行為實際上在5月發生了變化(錯誤14579); 在那之前,它確實是小數秒。不幸的是,這意味著有時它可以繞到一秒鐘是不可能的; 在錯誤報告中,當它應該轉到下一分鐘時,它上升到60。決定截斷而不是舍入的一個原因是它是從POSIXlt表示打印的,其中每個單元是分開存儲的。因此,滾動到下一分鐘/小時/等比僅僅簡單的舍入操作更困難。要輕松舍入,有必要在POSIXct表示中進行舍入,然后按照我的建議轉換回來。


查看完整回答
反對 回復 2019-08-27
  • 2 回答
  • 0 關注
  • 989 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號