更新/更好的答案:
看看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 和sapply,我们将返回一个命名的匹配向量。在grep 中设置value = TRUE 将返回字符串。
> (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,获取每个拆分中的最后一个元素,我们就完成了。
> 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 中的任何一个。这可能更好地解释here
然后,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 放入一行。由于函数和调用是从内向外评估的,因此在 R 到达外部 s 子集之前分配了 s。不过,这有点可读性差。
s[nzchar(s <- strsplit(x, "[: ]|[[:cntrl:]]")[[1]])][c(3,8,11)]
所以这将是s <- strsplit(...) -> [[ -> nzchar -> s[.. >- [c(3,8,11)]