将文本输出捕获为结构化数据框
capture text output as structured data frame
我将输出流式传输为以下形式的文本:
[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
捕获它,但我不太确定如何将它转换为数据框。
我认为您可以使用一些基本字符串函数来完成此操作。如果您将字符串存储在列表中,如下例所示,您可以创建一个函数来提取所需的信息,然后将其应用于列表并输出数据框:
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)))
输出可能会更漂亮,但我相信您可以稍微清理一下。如果您的所有数据都遵循相同的模式(即按空格分割并且您不希望等号前的位),它就会起作用。
另一种可能的解决方案,
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
数据
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 ")
我将输出流式传输为以下形式的文本:
[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
捕获它,但我不太确定如何将它转换为数据框。
我认为您可以使用一些基本字符串函数来完成此操作。如果您将字符串存储在列表中,如下例所示,您可以创建一个函数来提取所需的信息,然后将其应用于列表并输出数据框:
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)))
输出可能会更漂亮,但我相信您可以稍微清理一下。如果您的所有数据都遵循相同的模式(即按空格分割并且您不希望等号前的位),它就会起作用。
另一种可能的解决方案,
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
数据
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 ")