मैं एक आर फ़ंक्शन बनाना चाहता हूं जो एक बहुत ही विशेष काम करता है, और मैं इसे करने का एक और अधिक कुशल तरीका ढूंढ रहा हूं।

मूल रूप से, मुझे एक समारोह चाहिए

indicies<-function(increasing.series, multiple)

जो एक बढ़ती हुई श्रृंखला के संकेतकों को चुनता है जहां श्रृंखला का मूल्य एक निश्चित स्तर के गुणक से अधिक होता है। तो उदाहरण के लिए, यदि इनपुट एक वेक्टर है

testvector <- c(0.1, 0.5, 1.7, 2.1, 3.2, 4.5, 6.2, 6.3, 6.4, 7.9, 8.1)

परिणाम होगा

[1] 1  4  6  7 11

जहां यह धारण करता है

testvector[c(1,4,6,7,11)] == c(0.1, 2.1, 4.5, 6.2, 8.1)

ताकि फ़ंक्शन उन संकेतकों को चुन ले जहां श्रृंखला के मान पहले 2 (इंडेक्स 4, वैल्यू 2.1), 4 (इंडेक्स 6, वैल्यू 5.6), 6 (इंडेक्स 7, वैल्यू 6.2) और 8 (इंडेक्स 11, वैल्यू 8.1) से अधिक हो। ) परिप्रेक्ष्य के लिए, मैं दैनिक समय श्रृंखला से साप्ताहिक/मासिक/त्रैमासिक श्रृंखला चुनने का एक आसान तरीका प्राप्त करने के लिए इसका उपयोग करने की योजना बना रहा हूं। मैं कार्यान्वयन के रूप में इनपुट श्रृंखला के खिड़की वाले जोड़े पर किसी प्रकार के कार्यात्मक-जैसे कुल कार्य को चलाने के तरीके की उम्मीद कर रहा था, लेकिन मुझे यकीन नहीं है कि इसे संक्षेप में कैसे किया जाए। वर्तमान में, मैंने फ़ंक्शन को निम्नलिखित अधिक लंबे समय तक चलने वाले तरीके से कार्यान्वित किया है:

indicies<-function(increasing.series, multiple)
{
  # Create matrix with three columns: previous, current and orig.index, yielding
  # the previous and current value corresponding to an index in the original
  # series.
  pairs <- zoo::rollapply(data=increasing.series,width=2,identity)
  pairs <- rbind(c(NA, increasing.series[1]),pairs)
  pairs<-cbind(pairs,1:dim(pairs)[1])
  colnames(pairs) <- c("previous","current","orig.index")

  # This predicate returns true if the indexcorresponding to a row of the above matrix should
  # be included in the output.
  predicate <- function(row)
  {
    first <-  row["previous"]
    second <- row["current"]
    orig.index <- row["orig.index"] 
    firstRemainder <-  first  %% multiple
    secondRemainder <- second %% multiple

    # Include if the previous remainder is larger than the current or if the current timepoint
    # is a whole period in front of the previous.
    return(orig.index == 1 || firstRemainder > secondRemainder || second > first + multiple)
  }

  bool.indicies <- apply(pairs,1,predicate)
  return((1:length(bool.indicies))[bool.indicies])
}

क्या कोई बेहतर, छोटा, अधिक पठनीय तरीका है?

1
Alexander Sokol 28 नवम्बर 2017, 16:30

2 जवाब

सबसे बढ़िया उत्तर

यहाँ एक सरल उपाय है:

indicies <- function(increasing.series, multiple) {
  multiples <- (0:floor(max(increasing.series)/multiple)) * multiple
  sapply(multiples, function(x) which.max(increasing.series > x))
}
indicies(testvector, 2)
#[1]  1  4  6  7 11
1
jlesuffleur 28 नवम्बर 2017, 17:10

यहाँ मेरा दृष्टिकोण है:

c(1, which( diff( testvector %/% 2)>0) + 1)

इसके लिए वैरिएबल को परिभाषित करने या सैप्ली को कॉल करने की आवश्यकता नहीं है।

1
tobiaspk1 28 नवम्बर 2017, 19:00