2012-06-07 16 views
5

आर के तहत गोलिंग मिलीसेकंड के साथ निम्नलिखित समस्या को देखते हुए मैं इसके आसपास कैसे हो सकता हूं ताकि समय सही हो?आर राउंडिंग मिलीसेकंड

> options(digits.secs=3) 
> as.POSIXlt("13:29:56.061", format='%H:%M:%OS', tz='UTC') 
[1] "2012-06-07 13:29:56.060 UTC" 
> as.POSIXlt("13:29:56.062", format='%H:%M:%OS', tz='UTC') 
[1] "2012-06-07 13:29:56.061 UTC" 
> as.POSIXlt("13:29:56.063", format='%H:%M:%OS', tz='UTC') 
[1] "2012-06-07 13:29:56.063 UTC" 

मैंने देखा है कि इस URL पृष्ठभूमि जानकारी प्रदान करता है, लेकिन मेरी समस्या का समाधान नहीं करता है: Milliseconds puzzle when calling strptime in R

यह भी यूआरएल इस मुद्दे पर छूता है लेकिन इसे हल नहीं करता है: R xts: .001 millisecond in index

इन मामलों में मैं निम्नलिखित क्यों दिखाई देता है:

> x <- as.POSIXlt("13:29:56.061", format='%H:%M:%OS', tz='UTC') 
> print(as.numeric(x), digits=20) 
[1] 1339075796.0610001087 

URL भी संकेत मिलता है कि यह सिर्फ एक प्रदर्शन मुद्दा है लेकिन मैंने देखा है कि विकल्प लाइन के बिना "%OS3" जैसे बयानों का उपयोग कर ऐसा नहीं लगता है अंकों की सही संख्या पिकअप प्रतीत होता है।

संस्करण मैं उपयोग कर रहा हूँ 32 बिट 2.15.0 Windows के तहत है, लेकिन यह आर

के लिए अन्य स्थितियों के तहत अस्तित्व में

ध्यान दें कि अपने मूल डेटा एक CSV फ़ाइल मुझे लगता है चाहिए के भीतर इन दिनांक समय तार है लगता है एक स्ट्रिंग से सही मिलीसेकंद समय में उन्हें बदलने का एक तरीका।

+1

प्रारूप() का उपयोग अनावश्यक और विचलित है। । । – mdsumner

+0

ठीक है हाँ, लेकिन हमें 'प्रारूप ='% एच:% एम:% ओएस 'की आवश्यकता है। –

+0

यह भी देखें http://stackoverflow.com/a/7730759/210673 – Aaron

उत्तर

5

मुझे लगता है कि नहीं दिख रहा है:

> options(digits.secs = 4) 
> as.POSIXlt("13:29:56.061", format = '%H:%M:%OS', tz='UTC') 
[1] "2012-06-07 13:29:56.061 UTC" 
> as.POSIXlt("13:29:56.062", format = '%H:%M:%OS', tz='UTC') 
[1] "2012-06-07 13:29:56.062 UTC" 
> as.POSIXlt("13:29:56.063", format = '%H:%M:%OS', tz='UTC') 
[1] "2012-06-07 13:29:56.063 UTC" 
> options(digits.secs = 3) 
> as.POSIXlt("13:29:56.061", format = '%H:%M:%OS', tz='UTC') 
[1] "2012-06-07 13:29:56.061 UTC" 
> as.POSIXlt("13:29:56.062", format = '%H:%M:%OS', tz='UTC') 
[1] "2012-06-07 13:29:56.062 UTC" 
> as.POSIXlt("13:29:56.063", format = '%H:%M:%OS', tz='UTC') 
[1] "2012-06-07 13:29:56.063 UTC" 

साथ
> sessionInfo() 
R version 2.15.0 Patched (2012-04-14 r59019) 
Platform: x86_64-unknown-linux-gnu (64-bit) 

locale: 
[1] LC_CTYPE=en_GB.utf8  LC_NUMERIC=C    
[3] LC_TIME=en_GB.utf8  LC_COLLATE=en_GB.utf8  
[5] LC_MONETARY=en_GB.utf8 LC_MESSAGES=en_GB.utf8 
[7] LC_PAPER=C    LC_NAME=C     
[9] LC_ADDRESS=C    LC_TELEPHONE=C   
[11] LC_MEASUREMENT=en_GB.utf8 LC_IDENTIFICATION=C  

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods 
[7] base 
"%OSn" प्रारूप तार के साथ

, एक बलों काट-छांट। यदि आंशिक दूसरे को बिल्कुल फ़्लोटिंग पॉइंट्स में प्रदर्शित नहीं किया जा सकता है तो छंटनी गलत तरीके से जा सकती है। आप गलत तरीके से करने के लिए जा चीजों को देखने के साथ-साथ आप इकाई आप चाहते करने के लिए स्पष्ट रूप से दौर या अंश का आधा आप (मामले 0.0005 दिखाए जाने वाले इन) में काम करते करना चाहते हैं जोड़ सकते हैं:

> t1 <- as.POSIXlt("13:29:56.061", format = '%H:%M:%OS', tz='UTC') 
> t1 
[1] "2012-06-07 13:29:56.061 UTC" 
> t1 + 0.0005 
[1] "2012-06-07 13:29:56.061 UTC" 

(लेकिन एक मैंने कहा , मुझे यहां समस्या दिखाई नहीं दे रही है।)

यह बाद का बिंदु Simon Urbanek on the R-Devel mailing list on 30-May-2012 द्वारा बनाया गया था। (यह एक तर्क कुछ अन्य समारोह से नहीं आवश्यक इनपुट की नाम है प्रारूप यहाँ कॉल करने के लिए कोई ज़रूरत नहीं है,)

unclass(as.POSIXlt("13:29:56.061", '%H:%M:%OS', tz='UTC')) 
$sec 
[1] 56.061 
... 

:

+0

इसे 32 बिट संस्करण के साथ आज़माएं। –

+0

@AndrewStern मैं नहीं कर सकता कि मेरे पास 32-बिट सिस्टम नहीं है। मैंने अपना जवाब अपडेट कर लिया है। अपने समय में एक छोटा अंश (0.0005 अपने मामले में) जोड़ने का प्रयास करें * के बाद * आपको उन्हें "POSIXlt" 'ऑब्जेक्ट्स के रूप में मिला है और देखें कि क्या स्थिति में सुधार होता है या नहीं। अधिक जानकारी के लिए आर-डेवेल थ्रेड का पालन करें। –

+1

मैं पुन: उत्पन्न कर सकता हूं - मेरे पास Win7 64bit सिस्टम पर 32 बिट और 64 बिट आर दोनों स्थापित हैं। ऐसा लगता है कि समस्या 32 बिट आर – Fhnuzoag

1

मिलीसेकेंड देखते हैं।

अन्यथा, मैं (Windows 64-बिट आर 2.15.0 पर) पुन: पेश नहीं कर सकते हैं:

options(digits.secs = 3) 
as.POSIXlt("13:29:56.061", '%H:%M:%OS', tz='UTC') 
[1] "2012-06-07 13:29:56.061 UTC" 

sessionInfo() 
R version 2.15.0 Patched (2012-05-05 r59321) 
Platform: x86_64-pc-mingw32/x64 (64-bit) 
... 
+0

यह सही प्रतीत होता है जब मैं इसे निम्न का उपयोग करके अनवरोधित करता हूं: unclass (as.POSIXlt ("13: 2 9: 56.061", "% एच:% एम:% ओएस", tz = 'UTC') लेकिन स्क्रीन अब भी प्रदर्शित होने पर गलत मिलीसेकंड दिखाता है: as.POSIXlt ("13: 2 9: 56.061", "% एच:% एम:% ओएस", tz = 'UTC')।ध्यान दें कि मैं 32 बिट संस्करण पर हूं और 64 बिट संस्करण अधिक सटीक हो सकता है क्योंकि पंजीयक बड़े हैं। –

+1

एक दोषपूर्ण स्क्रीन होना चाहिए। – mdsumner

3

यह Milliseconds puzzle when calling strptime in R रूप में एक ही समस्या है।

आपका उदाहरण:

> x <- as.POSIXlt("13:29:56.061", format='%H:%M:%OS', tz='UTC') 
> print(as.numeric(x), digits=20) 
[1] 1339075796.0610001087 

समस्या के प्रतिनिधि नहीं है। as.numeric(x) संख्यात्मक रूप से परिवर्तित करने से पहले आपके POSIXlt ऑब्जेक्ट को POSIXct में परिवर्तित करता है, इसलिए आपको विभिन्न फ़्लोटिंग-पॉइंट-परिशुद्धता गोल करने वाली त्रुटियां मिलती हैं।

यह नहीं है कि print.POSIXlt (जो format.POSIXlt पर कॉल करता है) काम करता है। format.POSIXlt प्रारूपों POSIXlt सूची के प्रत्येक तत्व को अलग-अलग निर्माण, तो आप को देखने के लिए की आवश्यकता होगी:

print(x$sec, digits=20) 
[1] 56.060999999999999943 

और वह नंबर, तीसरे दशमलव स्थान पर काट दिया गया है, ताकि आप 56.060 देखते हैं।

> format(x, "%H:%M:%OS6") 
[1] "13:29:56.060999" 
1

परीक्षण में मैं ने कहा है कि यह समस्या अभी भी 32 बिट आर 3.01 के लिए मौजूद है और यह चल बिन्दु डेटा का एक काट-छांट के 32 बिट कार्यान्वयन के लिए विशिष्ट है की वजह से है कि: आप format सीधे फोन करके यह देख सकते POSIXlt दिनांक समय के लिए प्रिंट, प्रारूप और as.character ऑपरेटरों।

अंतर्निहित डेटा को एक अलग प्रकार में संग्रहीत नहीं किया गया है जो एक मामले (32 बिट) में छंटनी की ओर अग्रसर है और अन्य (64 बिट) नहीं, बल्कि "प्रिंट", "प्रारूप" और "as.character "POSIXlt प्रकार के लिए फ़ंक्शंस विशेष रूप से जो POSIXlt डेटा को प्रदर्शित करने योग्य स्ट्रिंग के रूप में प्रदर्शित करने के लिए उपयोग किया जाता है।

जबकि दस्तावेजी व्यवहार यह है कि ये फ़ंक्शंस अतिरिक्त अंकों को छेड़छाड़ (अनदेखा) करते हैं (जैसा कि @Gavin सिम्पसन द्वारा उल्लिखित है), यह 32 और 64 बिट संस्करणों के लिए भी सही नहीं है। प्रदर्शित करना; हम 1000 विभिन्न बार पैदा करते हैं और कुछ तुलना कार्रवाई होगी: के तहत दोनों 32 बिट और 64 बिट तुलना ऑपरेटरों संगत कर रहे हैं, तथापि के तहत 32 बिट मैं देख रहा हूँ

> options(digits.sec=3) 
> x = as.POSIXlt("13:29:56.061", format='%H:%M:%OS', tz='UTC') 

> for (i in 0:999) { 
>  x[i+1] = as.POSIXlt(paste0("13:29:56.",sprintf("%03d",i)),format='%H:%M:%OS',tz='UTC') 
> } 

> sum(x[2:1000]>x[1:999]) 
[1] 999 

:

> x[1:6] 
[1] "2015-10-16 13:29:56.000 UTC" "2015-10-16 13:29:56.000 UTC" 
[3] "2015-10-16 13:29:56.002 UTC" "2015-10-16 13:29:56.003 UTC" 
[5] "2015-10-16 13:29:56.003 UTC" "2015-10-16 13:29:56.005 UTC" 

तो यह है स्पष्ट रूप से एक प्रदर्शन मुद्दा। , POSIXlt डेटाप्रकार में वास्तविक संख्या को देखते हुए विशेष रूप से सेकंड हम देख सकते हैं कि क्या होने प्रकट होता है:

> y = (x[1:6]$sec) 
> y 
[1] 56.000 56.001 56.002 56.003 56.004 56.005 
> trunc(y*1000)/1000 
[1] 56.000 56.001 56.002 56.003 56.004 56.005 
> trunc((y-floor(y))*1000)/1000 
[1] 0.000 0.000 0.002 0.003 0.003 0.005 

मेरा सुझाव है कि यह एक बग है कि अंतर्निहित आधार पुस्तकालय में तय किया जाना चाहिए, एक अस्थायी ठीक के रूप में हालांकि, आप आउटपुट को अपने वांछित आउटपुट में बदलने के लिए "प्रिंट", "as.character" और "format" फ़ंक्शंस को ओवरराइट कर सकते हैं।

format.POSIXlt = function(posix) { 
    return(paste0(posix$year+1900,"-",sprintf("%02d",posix$mon+1),"-",sprintf("%02d",posix$mday)," ", 
     sprintf("%02d",posix$hour),":",sprintf("%02d",posix$min),":",sprintf("%002.003f",posix$sec))) 
    } 

print.POSIXlt = function(posix) { 
    print(paste0(posix$year+1900,"-",sprintf("%02d",posix$mon+1),"-",sprintf("%02d",posix$mday)," ", 
     sprintf("%02d",posix$hour),":",sprintf("%02d",posix$min),":",sprintf("%002.003f",posix$sec))) 
    } 

as.character.POSIXlt = function(posix) { 
    return(paste0(posix$year+1900,"-",sprintf("%02d",posix$mon+1),"-",sprintf("%02d",posix$mday)," ", 
     sprintf("%02d",posix$hour),":",sprintf("%02d",posix$min),":",sprintf("%002.003f",posix$sec))) 
    } 
संबंधित मुद्दे