更新/更好的答案:
看看这里cat(x)
有readLines(x)
很大帮助
> cat(x)
#
# Ticker Symbol: RBO
# Exchange: TSX
# Assets ($mm) 36.26 #
# Units Outstanding: 1,800,000
# Mgmt. Fee** 0.25
# 2013 MER* n/a
# CUSIP: 74932K103
> readLines(textConnection(x))
# [1] "" " Ticker Symbol: RBO"
# [3] " \t Exchange: TSX " "\t Assets ($mm) 36.26 "
# [5] "\t Units Outstanding: 1,800,000 " "\t Mgmt. Fee** 0.25 "
# [7] " 2013 MER* n/a " "\t CUSIP: 74932K103"
现在我们知道了一些事情。第一,我们不需要第一行,我们确实需要第二行。这使事情变得更容易,因为现在第一行与我们想要的第一行匹配。接下来,您的列表名称与字符串中的名称匹配会更容易。我选择了这些。
> nm <- c("Symbol", "Assets", "Units")
现在我们要做的就是使用grep
with sapply
,我们将得到一个命名的匹配向量。设置将返回我们value = TRUE
的grep
字符串。
> (y <- sapply(nm, grep, x = readLines(textConnection(x))[-1], value = TRUE))
# b Symbol Assets
# " Ticker Symbol: RBO" "\t Assets ($mm) 36.26 "
# Units
# "\t Units Outstanding: 1,800,000 "
然后我们strsplit
on "[: ]"
,取每个拆分中的最后一个元素,我们就完成了。
> lapply(strsplit(y, "[: ]"), tail, 1)
$Symbol
[1] "RBO"
$Assets
[1] "36.26"
$Units
[1] "1,800,000
你可以达到同样的结果
> g <- gsub("[[:cntrl:]]", "", capture.output(cat(x))[-1])
> m <- mapply(grep, nm, MoreArgs = list(x = g, value = TRUE))
> lapply(strsplit(m, "[: ]"), tail, 1)
希望有帮助。
原答案:
看起来如果你从一张大桌子上拉出这些,它们每次都会在同一个元素“槽”中,所以这可能会更容易一些。
> s <- strsplit(x, "[: ]|[[:cntrl:]]")[[1]]
解释:
-[: ]
匹配一个":"
字符后跟一个空格字符
-|
或
-[[:cntrl:]]
任何控制字符,在这种情况下是\r
,\t
和中的任何一个\n
。这可能在这里得到更好的解释
然后,nzchar
在上述结果中查找非零长度字符串,如果匹配则返回 TRUE,否则返回 FALSE。所以我们可以查看第一行的结果,确定匹配的位置,并以此为基础设置子集。
> as.list(s[nzchar(s)][c(3, 8, 11)])
[[1]]
[1] "RBO"
[[2]]
[1] "36.26"
[[3]]
[1] "1,800,000"
s
您可以通过指定为内部调用将 is 放入一行。由于函数和调用是从内向外评估的,s
因此在 R 到达外部s
子集之前分配。不过,这有点可读性差。
s[nzchar(s <- strsplit(x, "[: ]|[[:cntrl:]]")[[1]])][c(3,8,11)]
所以这会s <- strsplit(...)
-> [[
-> nzchar
-> s[..
>-[c(3,8,11)]