如何解析R中的分组文本数据并将其转换为数据帧/时间序列



我花了很多时间试图解析来自数据API的文本,该API将股票行情数据按包含在花括号内的组输出,数据格式如下:

/mktdata/ticker/AAA ?fields=ASK,BID:
MarketDataEvents = {
BID = 600
ASK = 605
BID_ASK_TIME = 09:47:48.000
}
/mktdata/ticker/AAA ?fields=ASK,BID:
MarketDataEvents = {
BID = 608
ASK = 610
BID_ASK_TIME = 09:47:49.000
}
/mktdata/ticker/AAA ?fields=ASK,BID:
MarketDataEvents = {
BID = 602
ASK = 605
BID_ASK_TIME = 09:47:50.000
}

我尝试按行解析以下内容,但似乎无法找到将此文本转换为表格的方法:

rawData <- readLines(paste (filepath, filename, sep="/"))
DataTab <- data.table(txt = rawData[!grepl(pattern = '\/mktdata/ticker/AAA ?fields=ASK,BID:', rawData)])

我希望看到的最终结果是:

BID ASK BID_ASK_TIME 
600 605 09:47:48.000
608 610 09:47:49.000
602 605 09:47:50.000

这是我第一次在这里请求帮助,如果我的问题不清楚,请随时评论。

谢谢你的帮助!

PS:实际数据在原始的"行为不佳"中是这样的;示例:

/mktdata/ticker/AAA ?fields=ASK,BID:
MarketDataEvents = {
BID = 600
BID_ASK_TIME = 09:50:48.000
}
/mktdata/ticker/AAA ?fields=ASK,BID:
MarketDataEvents = {
ASK = 610
LAST_PRICE = 610
BID_ASK_TIME = 09:50:49.000
}
/mktdata/ticker/AAA ?fields=ASK,BID:
MarketDataEvents = {
ASK = 605
LAST_PRICE = 610    
BID_ASK_TIME = 09:50:50.000
}
/mktdata/ticker/AAA ?fields=ASK,BID:
MarketDataEvents = {
BID = 599
BID_ASK_TIME = 09:51:05.000
LAST_PRICE = 601
}

您可以只保留文本中具有特定模式的行。在这里,我保留了一个单词后面跟着=和一个数字的行,把它们放在一个矩阵中并将其转换为数据帧。

为了可读性,我使用了管道(%>%)。

library(magrittr)
rawData <- readLines(paste(filepath, filename, sep="/"))
matrix(grep('\w+ = \d+', rawData, value = TRUE), ncol = 3, byrow = TRUE) %>%
sub('.*=\s', '', .) %>%
as.data.frame() %>%
type.convert(as.is = TRUE) %>%
setNames(c('BID', 'ASK', 'BID_ASK_TIME')) -> DataTab
DataTab
#  BID ASK BID_ASK_TIME
#1 600 605 09:47:48.000
#2 608 610 09:47:49.000
#3 602 605 09:47:50.000

对于更新后的数据集,我们可以找到{}的位置,并在它们之间创建一个序列。我们使用正则表达式提取它们之间的数据,并将它们绑定到一个数据框中。

rawData <- readLines(paste (filepath, filename, sep="/"))
open <- grep('{', rawData, fixed = TRUE)
close <- grep('}', rawData, fixed = TRUE)
dplyr::bind_rows(Map(function(x, y) {
tmp <- stringr::str_match(rawData[x:y], '(\w+) = (.*)') 
setNames(data.frame(t(tmp[, 3])), tmp[, 2])
}, open + 1, close-1)) -> result

result
#   BID BID_ASK_TIME  ASK LAST_PRICE
#1  600 09:50:48.000 <NA>       <NA>
#2 <NA> 09:50:49.000  610        610
#3 <NA> 09:50:50.000  605        610
#4  599 09:51:05.000 <NA>        601

最新更新