2015-02-09 15 views
12

मैंने +0L को एक प्रश्न के उत्तर में उपयोग किया और पाया कि यह matrices/डेटा फ्रेम/डेटा टेबल के साथ अच्छी तरह से काम करता है जहां as.integer() प्रारंभिक डेटा कक्षाओं को संरक्षित करने में असमर्थ होगा।बूलियन पर as.integer() और + 0L के बीच क्या अंतर है?

> a <- matrix(TRUE, nrow=3, ncol=3) 
> a 
    [,1] [,2] [,3] 
[1,] TRUE TRUE TRUE 
[2,] TRUE TRUE TRUE 
[3,] TRUE TRUE TRUE 
> as.integer(a) 
[1] 1 1 1 1 1 1 1 1 1 
> a+0L 
    [,1] [,2] [,3] 
[1,] 1 1 1 
[2,] 1 1 1 
[3,] 1 1 1 
  • इन तरीकों के बीच वहाँ अन्य मतभेद है?
  • एक या दूसरे का उपयोग करते समय पेशेवरों और विपक्ष और चेतावनी क्या हैं?

[संपादित करें]] टिप्पणियों में बहुत सारे ज्ञान!

  • प्राप्त करने के लिए क्या a+0L करता अन्य तरीके क्या हैं: जाहिर है वहाँ एक ही परिणाम प्राप्त करने के लिए कई अलग अलग तरीकों, जिनमें से कुछ के बारे में मैं नहीं था, इसलिए है?
+3

मूल आयामों प्राप्त करने के लिए ' 'मंद <-' (as.integer (क), मंद (क))'। यदि वहाँ 'तत्वों में से एक के रूप में Inf',' as.integer' यह 'NA' को, coerces जबकि' + 0L' 'देता है कि तत्व – akrun

+3

या सिर्फ' एक [] <के लिए Inf' मूल्य - as.integer (क) '। हालांकि यह सवाल का जवाब नहीं देता है। –

+3

या, 'storage.mode (ए) <- "पूर्णांक" ' – James

उत्तर

15

x + 0L एक तत्व बुद्धिमानx पर आपरेशन है; इस प्रकार, यह अक्सर डेटा के आकार को संरक्षित करता है। as.integer नहीं है: यह पूरी संरचना लेता है - यहां, एक मैट्रिक्स - और इसे एक-आयामी पूर्णांक वेक्टर में परिवर्तित करता है।

उसने कहा, सामान्य मामले में मैं दृढ़ता से as.integer का उपयोग करने का सुझाव देता हूं और एक चतुर हैक के रूप में + 0L को हतोत्साहित करता हूं (याद रखें: अक्सर, चालाक ≠ अच्छा)। मैं टिप्पणी से डेविड की पद्धति का उपयोग करके आप डेटा के आकार को संरक्षित करना चाहते हैं का सुझाव देते हैं, बल्कि + 0L हैक से:

a[] = as.integer(a) 

यह as.integer के सामान्य अर्थ का उपयोग करता है, लेकिन परिणाम के व्यक्तिगत तत्वों को सौंपा गया है a, a के बजाय ही। दूसरे शब्दों में, a का आकार छूटा हुआ है।

+2

दृढ़ता से इस बात से सहमत। मुझे आश्चर्य है कि कैसे 'storage.mode (क) <-" पूर्णांक "' (के रूप में @James से ऊपर टिप्पणी की) पारदर्शिता और दक्षता –

+0

मुझे लगता है कि 'के मामले में तुलना" storage.mode <- "' के लिए और अधिक औपचारिक तरीके से किया जाना चाहिए ऐसा करें क्योंकि यह सिर्फ coerces और गुण रखता है। '" [<- "', दूसरी तरफ, 'as.integer (ए)' में जबरन जरूरी है और जब भी "पूर्णांक" को उपनिवेशित किया जाता है, फिर भी, "तार्किक" 'a'। एक बेंचमार्क: 'एम 1 = एम 2 = मैट्रिक्स (सत्य, 1e4, 1e3); system.time ({m1 [] = as.integer (m1)}); system.time ({storage.mode (एम 2) = "पूर्णांक"}) ' –

+1

@alexis_laz मुझे लगता है कि मैं' storage.mode <-' विधि बहुत अस्पष्ट लगता है स्वीकार करना होगा। यह अनिवार्य रूप से वही करता है ('मोड <-' वास्तव में सदस्यों पर 'as.xyz' को कॉल करेगा,' storage.mode <-' अवधारणात्मक रूप से वही है, लेकिन अधिक अनुकूलित) 'as.integer' के रूप में, लेकिन बहुत कम स्पष्ट तरीके से। –

11

0L जोड़ा जा रहा है को बढ़ावा देता है a रूप ?Arithmetic में वर्णित पूर्णांक तक:

तार्किक वैक्टर पूर्णांक या संख्यात्मक वैक्टर, गलत मूल्य शून्य और सही होने मूल्य होने मजबूर कर दिया जाएगा।

एक परिणाम के रूप में किसी भी अंकगणितीय संचालन a और कहा कि ऑपरेशन के लिए पहचान तत्व का उपयोग (लेकिन नहीं है कुछ बिंदु पर सांख्यिक पर जाने के लिए, जैसे / और ^) काम करेगा:

a+0L 
a-0L 
a*1L 
a%/%1 

एकल आपरेशन भी काम करेंगे, तो शायद "सर्वश्रेष्ठ" कोड गोल्फ संस्करण है:

--a 

यह usin के आम चाल के साथ एक समानांतर है जी !!a एक संख्यात्मक वस्तु को तार्किक रूपांतरित करने के लिए।

identical(a+0L, a-0L, a*1L, a%/%1L, --a) 
[1] TRUE 

तार्किक करने के लिए वापस परिवर्तित:

storage.mode(a) <- "integer" 
a 
    [,1] [,2] [,3] 
[1,] 1 1 1 
[2,] 1 1 1 
[3,] 1 1 1 
+0

आह, ज्ञान के लिए पुराना व्यवस्थित दृष्टिकोण - अंतर्निहित सिद्धांतों को प्रकट करता है! – LauriK

4

(यह जवाब नहीं अन्य जोड़ता है:

identical(a, !!--a) 
[1] TRUE 

एक वैकल्पिक, और शायद स्पष्ट, दृष्टिकोण सीधे a की storage.mode बदलने के लिए है पहले से मौजूद लोगों के लिए विकल्प, लेकिन मैं सिर्फ इस थ्रेड में टिप्पणियों को साफ करने के लिए पोस्ट कर रहा हूं।)

as.integer, परिभाषा द्वारा, as.vector की तरह बर्ताव करता है, यानी यह सभी विशेषताओं स्ट्रिप्स ("मंद" शामिल है) एक अनुसंधान वेक्टर बनाने के लिए। यह एक ही ऑब्जेक्ट को बदले typeof के साथ वापस नहीं करेगा। जबरदस्ती के बाद गुणों को बहाल करने के लिए, "dim<-", "names<-", "class<-" इत्यादि स्पष्ट रूप से या किसी फ़ंक्शन के माध्यम से कहा जाना चाहिए जो इसके तर्कों के गुणों को संग्रहीत करता है (उदा। "[<-")। जैसे "dim<-"(as.integer(a), dim(a)) या array(as.integer(a), dim(a)) या a[] <- as.integer(a)। एक बेंचमार्क:

x = matrix(T, 1e3, 1e3) 
microbenchmark::microbenchmark("dim<-"(as.integer(x), dim(x)), 
           array(as.integer(x), dim(x)), 
           { x[] = as.integer(x) }, times = 25) 
#Unit: milliseconds 
#       expr  min  lq median  uq  max neval 
# `dim<-`(as.integer(x), dim(x)) 1.650232 1.691296 2.492748 4.237985 5.67872 25 
# array(as.integer(x), dim(x)) 6.226130 6.638513 8.526779 8.973268 47.50351 25 
# {  x[] = as.integer(x) } 7.822421 8.071243 9.658487 10.408435 11.90798 25 

ऊपर में, "dim<-" justs बनाया as.integer(x) को एक विशेषता, array बनाया as.integer(x) स्टोर करने के लिए एक नया वेक्टर, और "[<-" परिवर्तन "x" इतना है कि यह स्वीकार कर सकते हैं के मूल्यों आवंटित कहते हैं as.integer(x) बनाया और फिर, अपने नए मान डालने के लिए "x" के माध्यम से पुनरावृत्त करता है।

x = as.character(1:5) 
x 
#[1] "1" "2" "3" "4" "5" 
x[] = as.integer(x) 
x 
#[1] "1" "2" "3" "4" "5" 

या::

x = 1:5 
x 
#[1] 1 2 3 4 5 
x[] = as.logical(x) 
x 
#[1] 1 1 1 1 1 

लेकिन:

x = round(runif(5), 2) 
x 
#[1] 0.68 0.54 0.02 0.14 0.08 
x[] = as.character(x) 
x 
#[1] "0.68" "0.54" "0.02" "0.14" "0.08" 

यानी

"[<-" विधि है, हालांकि, एक नुकसान है प्रतिस्थापन ऑब्जेक्ट के typeoftypeof प्रतिस्थापन योग्य ऑब्जेक्ट के "[<-"typeof को नहीं बदलेगा। Subassignment (अर्थात "[<-") coerces या तो वस्तु को बदल देना चाहिए या की जगह वस्तु या कोई भी उनके typeof रों पर निर्भर करता है (इस SubassignTypeFix द्वारा किया जाता है)। @ जोश ओ'ब्रायन "[<-" के व्यवहार में मौजूद होने की संभावना को नोट करते हैं यदि सूचकांक गुम हैं। ईमानदार होने के लिए, मुझे इस तरह के मामले में एक विशिष्ट उपचार नहीं मिला, उदाहरण के लिए, उदाहरण के लिए do_subset_dflt ("[") अप्रत्यक्ष रूप से लापताता को संभालता है।

जैसा कि पहले ही उल्लेख किया है, वहाँ है, भी, "storage.mode<-" एक वस्तु का typeof बदलने के लिए:

"storage.mode<-"(as.character(1:5), "integer") 
#[1] 1 2 3 4 5 
"storage.mode<-"(1:5, "logical") 
#[1] TRUE TRUE TRUE TRUE TRUE 
"storage.mode<-"(round(runif(5), 2), "character") 
#[1] "0.09" "0.38" "0.98" "0.73" "0.81" 

x = matrix(T, 1e3, 1e3) 
microbenchmark::microbenchmark("storage.mode<-"(x, "integer"), 
           "dim<-"(as.integer(x), dim(x)), times = 25) 
#Unit: milliseconds 
#       expr  min  lq median  uq  max neval 
# `storage.mode<-`(x, "integer") 1.986055 2.01842 2.147181 2.406096 6.019415 25 
# `dim<-`(as.integer(x), dim(x)) 1.984664 2.02016 2.111684 2.613854 6.174973 25 

"dim<-" को दक्षता में इसी प्रकार के बाद से वे दोनों एक बार विवश और एक विशेषता की दुकान।

बाइनरी ऑपरेशंस (जैसा कि जेम्स और कोनराड रुडॉल्फ द्वारा उल्लिखित) उनके तर्कों को उपयुक्त typeof पर केंद्रित करते हैं और गुण ("मंद", "नाम", "वर्ग" इत्यादि रखते हैं।) दो तर्कों के नियमों के आधार पर। (धारा "मान" ?Arithmetic में)

संबंधित मुद्दे