2014-10-16 7 views
5

मेरे पास मौजूदा आर सत्र में एक बड़ा data.frame (15 कॉलम और 100,000 पंक्तियां) हैं जो मैं एक क्यू/केडीबी उदाहरण में भेजना चाहता हूं। KDB's cookbook से, संभव समाधान हैं:आर से क्यू/केडीबी तक डेटा.फ्रेम कैसे भेजें?

RServer for Q: उपयोग KDB नई आर उदाहरण है, जिसमें स्मृति स्थान के शेयरों बनाने के लिए। यह काम नहीं करता क्योंकि मेरे डेटा एक मौजूदा उदाहरण आर

RServe की में है: एक अनुसंधान सर्वर चलाने के लिए और क्यू/KDB ग्राहक के साथ संवाद करने के लिए टीसीपी/आईपी का उपयोग करें। यह काम नहीं करता है, क्योंकि RServe's documentation के अनुसार, "प्रत्येक कनेक्शन में एक अलग वर्कस्पेस और कार्यशील निर्देशिका है" और इसलिए मुझे लगता है कि मेरा मौजूदा डेटा नहीं दिख रहा है।

R Math Library: आर इस का एक उदाहरण की जरूरत के बिना एक गणित पुस्तकालय के माध्यम से पहुँच आर की कार्यक्षमता काम नहीं करता क्योंकि मेरे डेटा आर

का एक उदाहरण में पहले से ही है तो डेटा भेजने के लिए कैसे पर किसी भी अन्य विचारों आर से क्यू/केडीबी तक?

उत्तर

2

प्र में एक बंदरगाह खोलने मैं एक बैच फ़ाइल के साथ क्यू शुरू:

@echo off 
c:\q\w32\q -p 5001 

लोड qserver.dll

tryCatch({ 
dyn.load("c:/q/qserver.dll")} 
    ,error = function(f){ 
    print("can't load qserver.dll") 
    }) 

फिर इन

open_connection <- function(host="localhost", port=5001, user=NULL) { 
     parameters <- list(host, as.integer(port), user) 
     h <- .Call("kx_r_open_connection", parameters) 
    assign(".k.h", h, envir = .GlobalEnv) 
    return(h) 
} 

close_connection <- function(connection) { 
     .Call("kx_r_close_connection", as.integer(connection)) 
} 

execute <- function(connection, query) { 
     .Call("kx_r_execute", as.integer(connection), query) 
} 

d<<-open_connection(host="localhost",port=thePort) 

ex2 <- function(...) 
{ 
    query <- list(...) 
    theResult <- NULL 
    for(i in query) theResult <- paste0(theResult,i) 
    return(execute(d,paste0(theResult))) 
} 

तो ex2 ले जा सकते हैं का उपयोग करें कई तर्क इसलिए आप आर चर के साथ प्रश्न बना सकते हैं और तार

संपादित करें: क्यू से आर, यहाँ क्यू

2 संपादित करने के लिए आर के लिए thats:

library(stringr) 
    RToQTable <- function(Rtable,Qname,withColNames=TRUE,withRowNames=TRUE,colSuffix = NULL) 
{ 
    theColnames <- if(!withColNames || length(colnames(Rtable))==0) paste0("col",as.character(1:length(Rtable[1,])),colSuffix) else colnames(Rtable) 
    if(!withRowNames || length(rownames(Rtable))==0) withRowNames <- FALSE 
    Rtable <- rbind(Rtable,"linesep") 
    charnum <- as.integer(nchar(thestr <- paste(paste0(theColnames,':("',str_split(paste(Rtable,collapse='";"'),';\"linesep\";\"')[[1]],');'),collapse="")) - 11) 
    if(withRowNames) 
    ex2(Qname,":([]",Qname,str_replace_all(paste0("`",paste(rownames(Rtable),collapse="`"))," ","_"),";",.Internal(substr(thestr,1L,charnum)),"))") else 
    ex2(Qname,":([]",.Internal(substr(thestr,1L,charnum)),"))") 
} 

> bigMat <- matrix(runif(1500000),nrow=100000,ncol=15) 
> microbenchmark(RToQTable(bigMat,"Qmat"),times=3) 
Unit: seconds 
         expr  min  lq  mean median  uq  max neval 
RToQTable(bigMat, "Qmat") 10.29171 10.315 10.32766 10.33829 10.34563 10.35298  3 

यह बहुत के लिए एक डेटा फ्रेम बस प्रकार युक्त एक सदिश बचाने के लिए, एक मैट्रिक्स के लिए काम करेंगे: algo सुधार प्रत्येक कॉलम के बाद, डेटाफ्रेम को मैट्रिक्स में कनवर्ट करें, क्यू में मैट्रिक्स आयात करें, और

नोट करें कि यह अलगो लगभग ओ (पंक्तियों * कोल्स^1.1) है, इसलिए आपको कॉलम को काटना होगा कई मैट्रिक्स में यदि आपके पास ओ (पंक्तियां * कोल्स)

प्राप्त करने के लिए 20 से अधिक है

लेकिन आपके उदाहरण के लिए 150,000 पंक्तियां और 15 कॉलम 10 सेकंड लेते हैं ताकि आगे अनुकूलन आवश्यक न हो।

+1

धन्यवाद, लेकिन आपका समाधान केवल [क्यू-सर्वर के लिए आर] (http://code.kx.com/wiki/Cookbook/IntegratingWithR#Calling_kdb.2B_from_R) का उपयोग कर ** ** के भीतर पूछताछ क्यू के बारे में बात करता है। मुझे आर से क्यू ** तक 15 कॉलम और 100,000 पंक्तियों के साथ 'data.frame' भेजने की आवश्यकता है। क्या आप आर से क्यू से बड़े 'डेटा.फ्रेम' भेज सकते हैं? – mchen

+0

ओह व्हाउप्स, मैं – hedgedandlevered

+0

संपादित करूंगा क्या यह मदद मिली? कृपया अगर स्वीकार करें, तो मुझे बताएं कि मैं – hedgedandlevered

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