2014-10-16 15 views
5

Ho un grande data.frame (15 colonne e 100.000 righe) in una sessione R esistente che voglio inviare a un'istanza Q/KDB. Da KDB's cookbook, le soluzioni possibili sono:Come inviare un data.frame da R a Q/KDB?

RServer for Q: uso KDB creare nuova istanza R che condivide lo spazio di memoria. Questo non funziona perché il mio dati è in una esistente un'istanza di R.

RServe: eseguire un server R e utilizzare il protocollo TCP/IP per comunicare con il cliente Q/KDB. Questo non funziona, perché come da RServe's documentation, "ogni connessione ha uno spazio di lavoro separato e una directory di lavoro" e quindi presumo che non veda i miei dati esistenti.

R Math Library: funzionalità l'accesso di R tramite una libreria matematica senza bisogno di un'istanza di R. Questo non funziona perché il mio dati sono già in un'istanza di R.

Quindi altre idee su come inviare i dati da R a Q/KDB?

risposta

2

aprire una porta in Q. comincio Q con un file batch:

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

carico qserver.dll

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

Poi usare queste

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))) 
} 

poi EX2 può prendere più argomenti in modo da poter creare query con variabili R e stringhe

Modifica: thats per R da Q, ecco R a Q

2a Modifica: migliorate algo:

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 

questo lavoro per una matrice, quindi per un frame di dati solo salvare un vettore contenente i tipi di ogni colonna, quindi convertire il dataframe in una matrice, importare la matrice in Q e lanciare i tipi

Si noti che questo algo è di circa O (righe * colonne 1.1), quindi è necessario tagliare le colonne verso l'alto in più matrici se ne avete più di 20 per ottenere O (rows * cols)

ma per il tuo esempio 150.000 righe e 15 colonne impiegano 10 secondi, quindi ulteriori ottimizzazioni potrebbero non essere necessarie.

+1

Grazie, ma la soluzione parla solo di ** query Q dall'interno R ** utilizzando [Q-Server per R] (http://code.kx.com/wiki/Cookbook/IntegratingWithR#Calling_kdb.2B_from_R). Ho bisogno di inviare un 'data.frame' con 15 colonne e 100.000 righe ** da R a Q **. Potresti dimostrare di inviare un grande 'data.frame' da R a Q, per favore? – mchen

+0

ohh whoops, modifico – hedgedandlevered

+0

Questo aiuto? per favore accettate se è così, se non fatemi sapere cosa posso aggiungere – hedgedandlevered

Problemi correlati