सवाल आर डेटाटेबल स्लाइडिंग विंडो


डेटाटेबल पैकेज के साथ एक स्लाइडिंग विंडो फ़ंक्शन को कार्यान्वित करने का सबसे अच्छा (तेज़ तरीका) क्या है?

मैं एक रोलिंग औसत की गणना करने की कोशिश कर रहा हूं लेकिन प्रति दिन कई पंक्तियां हैं (2 अतिरिक्त कारकों के कारण), जो मुझे लगता है कि चिड़ियाघर रोलप्ली फ़ंक्शन काम नहीं करेगा। लूप के लिए एक बेवकूफ का उपयोग कर एक उदाहरण यहां दिया गया है:

library(data.table)
df <- data.frame(
  id=30000,
  date=rep(as.IDate(as.IDate("2012-01-01")+0:29, origin="1970-01-01"), each=1000),
  factor1=rep(1:5, each=200),
  factor2=1:5,
  value=rnorm(30, 100, 10)
)

dt = data.table(df)
setkeyv(dt, c("date", "factor1", "factor2"))

get_window <- function(date, factor1, factor2) {
  criteria <- data.table(
    date=as.IDate((date - 7):(date - 1), origin="1970-01-01"),
    factor1=as.integer(factor1),
    factor2=as.integer(factor2)
  )
  return(dt[criteria][, value])
}

output <- data.table(unique(dt[, list(date, factor1, factor2)]))[, window_median:=as.numeric(NA)]

for(i in nrow(output):1) {
  print(i)
  output[i, window_median:=median(get_window(date, factor1, factor2))]
}

45
2017-07-26 19:15


मूल


+1 भी क्या आप डेटा आकार और समय के बारे में अधिक जानकारी प्रदान कर सकते हैं। आपकी टिप्पणी से एलन के उत्तर में (एलन और एलन अलग-अलग लोग हैं?), इसमें 6.4s (बनाम 973 के लिए data.frame) और आप 6.4 एस आगे सुधारना चाहते हैं? - Matt Dowle
एलन और एलन अलग-अलग लोग हैं :)। डेटासेट में ~ 650,000 पंक्तियां हैं। मैं ऐसे समाधान के साथ आया जो बहुत तेजी से काम करता है लेकिन बहुत यादगार गहन है। इस पर कोई विचार कैसे आगे बढ़ाया जा सकता है? - alan


जवाब:


data.table वर्तमान में रोलिंग विंडो के लिए कोई विशेष विशेषताएं नहीं हैं। यहां एक और समान प्रश्न के उत्तर में यहां और विवरण दिया गया है:

वहां एक उपवास data.table के अंदर एक रोलिंग रिग्रेशन चलाने के लिए रास्ता?

रोलिंग औसत दिलचस्प है। इसे कुशलता से करने के लिए एक विशेष कार्य की आवश्यकता होगी (पहले की टिप्पणी में जैसा ही लिंक):

सी में रोलिंग औसत एल्गोरिदम

data.table प्रश्न और उत्तर में समाधान सभी उचित अक्षम हैं, एक उचित विशेष के सापेक्ष rollingmedian समारोह (जो आर afaik के लिए उपलब्ध नहीं है)।


7
2017-08-31 11:26



क्या हम एफआर # 2185 की प्राथमिकता बढ़ा सकते हैं? "विंडोज़ स्लाइडिंग के लिए विशेषताएं / दस्तावेज जोड़ें"। मेरे परिप्रेक्ष्य से इसे किसी भी रोल योग, माध्य इत्यादि की आवश्यकता नहीं है। "फ्रेमफन =" या नीचे दिए गए तरीकों के प्रकार के ढांचे को बेहतर बनाना बेहतर है: मैंने पहले ही रोल = 30, बहु = 'सब', allow.cartesian सफलता के बिना इसे प्राप्त करने के लिए। इसके अलावा "एन" वेक्टर को स्वीकार करने के लिए अच्छा होगा, न केवल स्केलर। - jangorecki
@MusX ठीक है, मैंने शीर्ष पर प्राथमिकता बढ़ा दी है। - Matt Dowle


मैं एक लेटे हुए डेटासेट बनाकर और एक बड़ी जुड़ाव करके 1.4s तक उदाहरण प्राप्त करने में कामयाब रहा।

df <- data.frame(
  id=30000,
  date=rep(as.IDate(as.IDate("2012-01-01")+0:29, origin="1970-01-01"), each=1000),
  factor1=rep(1:5, each=200),
  factor2=1:5,
  value=rnorm(30, 100, 10)
)

dt2 <- data.table(df)
setkeyv(dt, c("date", "factor1", "factor2"))

unique_set <-  data.table(unique(dt[, list(original_date=date, factor1, factor2)]))
output2 <- data.table()
for(i in 1:7) {
  output2 <- rbind(output2, unique_set[, date:=original_date-i])
}    

setkeyv(output2, c("date", "factor1", "factor2"))
output2 <- output2[dt]
output2 <- output2[, median(value), by=c("original_date", "factor1", "factor2")]

यह इस परीक्षण डेटासेट पर बहुत अच्छी तरह से काम करता है लेकिन मेरे असली पर यह 8 जीबी रैम के साथ विफल रहता है। मैं इसे काम करने के लिए हाई मेमोरी ईसी 2 इंस्टेंस (17, 34 या 68 जीबी रैम के साथ) में जाने की कोशिश करने जा रहा हूं। कम स्मृति गहन तरीके से इसे कैसे करें इस पर कोई विचार सराहना की जाएगी


4
2017-08-10 15:00



बस पहली नज़र में, rbind के अंदर for बहुत अधिक रैम का उपयोग करेंगे। उस बिट को करने का एक और सीधा तरीका होना चाहिए। - Matt Dowle
यह प्रश्न मध्यस्थ रोलिंग के लिए बाइनरी खोज, आर और सी का उल्लेख है। आगे की जांच करने के लिए आपके लिए वादा करता है; यानी, के बारे में सोचो कलन विधि। - Matt Dowle


यह समाधान काम करता है लेकिन इसमें कुछ समय लगता है।

df <- data.frame(
  id=30000,
  date=rep(seq.Date(from=as.Date("2012-01-01"),to=as.Date("2012-01-30"),by="d"),each=1000),
  factor1=rep(1:5, each=200),
  factor2=1:5,
  value=rnorm(30, 100, 10)
)

myFun <- function(dff,df){
    median(df$value[df$date>as.Date(dff[2])-8 & df$date<as.Date(dff[2])-1 & df$factor1==dff[3] & df$factor2==dff[4]])
}

week_Med <- apply(df,1,myFun,df=df)

week_Med_df <- cbind(df,week_Med)

0
2017-07-27 15:28



धन्यवाद! ऐसा लगता है कि हालांकि लूप के लिए लंबा समय लगता है। सिस्टम से प्राप्त होने वाले समय लूप के लिए आपके कोड 6.4s के लिए 973 हैं। मुझे लगता है कि अंतर डेटा.table पैकेज का उपयोग होना चाहिए - alan