2016-03-04 46 views
-4

我有输出流作为文本在以下形式:捕获文本输出作为结构化数据帧

[2] "TWS OrderStatus: orderId=12048 status=PreSubmitted 
         filled=0 remaining=300 averageFillPrice=0 " 

[3] "TWS OrderStatus: orderId=12049 status=PreSubmitted 
         filled=0 remaining=300 averageFillPrice=0 " 

我想捕捉这样的输出,并将它与列转换为一个数据帧:orderId, status, filled, remaining, averageFillPrice

我想知道什么是最有效的方式来做到这一点。

我试图用capture.output捕获它,但后来我不确定如何将它转换为数据帧。

+0

你的意思是 “流”? – nrussell

+0

该功能连接到财务网站,并在发生时返回信息。不管怎样,我在5秒内关闭连接 – kalka

+0

我们很难重现您的程序。你正在通过“功能”来讨论“输出流”,这使我们很难考虑如何帮助你。我们甚至不知道您捕获的输出是什么类型的对象。请阅读http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – coffeinjunky

回答

1

我想你可以用一些基本字符串函数来做到这一点。如果你已经存储在列表中的字符串,如下面的例子,你可以创建一个函数来提取所需的信息,然后把它应用到列表和输出的数据帧:

a <- "TWS OrderStatus: orderId=12048 status=PreSubmitted filled=0 remaining=300 averageFillPrice=0 " 
b <- "TWS OrderStatus: orderId=12049 status=PreSubmitted filled=0 remaining=300 averageFillPrice=0 " 
dat <- list(a, b) 

extract <- function(x) { 
    a <- as.vector(strsplit(x, " ")[[1]])[-(1:2)] 
    return(sapply(a, function(b) substr(b, gregexpr("=", b)[[1]] + 1, nchar(b)))) 
} 

as.data.frame(t(sapply(dat, extract))) 

输出可以比较漂亮,但我相信你可以把它清理一下。如果您的所有数据遵循相同的模式(即按空格拆分,并且您不想在等号之前的位),那么它就可以工作。

+0

谢谢丹。这工作完美:) – kalka

+0

没有probs,你想接受答案,如果它是最好的? –

0

另一种可能的解决方案,

library("splitstackshape") 
library("stringr") 
makedf <- function(x) { 
v1 <- str_split(trimws(sub(".*?:(.+)", "\\1", x)), " ") 
v3 <- as.data.frame(sapply(v1, function(i) t(i))) 
v4 <- as.data.frame(t(cSplit(v3, "V1", "="))) 
v4[] <- lapply(v4, as.character) 
colnames(v4) <- v4[1,] 
v4 <- v4[-1,] 
    } 
FinalDF <- rbindlist(lapply(txt, makedf)) 
FinalDF 
# orderId  status filled remaining averageFillPrice 
#1: 12048 PreSubmitted  0  300    0 
#2: 12049 PreSubmitted  0  300    0 

DATA

txt <- list("TWS OrderStatus: orderId=12048 status=PreSubmitted filled=0 remaining=300 averageFillPrice=0 ", 
    "TWS OrderStatus: orderId=12049 status=PreSubmitted filled=0 remaining=300 averageFillPrice=0 ")