Одним из решений может быть сопоставление позиций символов всех векторов.
Во-первых, может быть полезно, если все строки имеют одинаковое количество символов.Мы можем достичь этого, добавив немного пробела в конце.
# list string vector --
tl <- as.list(tx)
# make equal length --
tl <- lapply(tl, function(x) {
d <- max(sapply(tl, nchar)) - nchar(x)
if (d > 0) paste(x, Reduce(paste0, rep(" ", d - 1)))
else x
})
# check equal num. of chars.
sd(sapply(tl, nchar))
# [1] 0 # ok
Затем мы напишем функцию разбиения, которая обрезает вектор при его скачках последовательности.
splitAtCuts <- function(x)
split(x, cut(x, x[which(c(2, diff(x[- length(x)]), length(x)) > 1)],
include.lowest=TRUE, right=FALSE))
Теперь мы можем сопоставитьположение символов в два шага.
# get character position matches --
# step 1
sl <- lapply(tl, function(x) {
w <- which(strsplit(x, "")[[1]] != " ")
return(splitAtCuts(w))
})
# step 2
pos <- sort(Reduce(union, unlist(sl)))
Теперь, когда мы знаем, где находятся символы, мы можем получить положения столбцов,
# extract column positions --
cols <- splitAtCuts(pos)
, которые помогают нам разрезать список строк вжелаемая матрица.
# cut into a matrix --
FUN <- Vectorize(function(x, y)
substring(tl[[x]], min(cols[[y]]), max(cols[[y]])))
M <- outer(seq(length(tl)), seq(length(cols)), FUN)
Наконец мы применяем некоторую очистку.
M <- apply(M, 2, function(x) gsub("^\\s|\\s{2,}|\\s$", "", x))
M
Уступ
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] "" "" "" "" "" ""
[2,] "" "" "" "Total" "" ""
[3,] "" "" "" "Dividend" "" ""
[4,] "" "" "Proportion" "Gain" "" ""
[5,] "Year" "Dividend Gain" "Earned" "(1) x (2)" "Dividend Gain" "Misc Gain"
[6,] "–––––" "–––––" "–––––" "–––––" "–––––" "–––––"
[,7] [,8] [,9]
[1,] "" "" "Total"
[2,] "" "" "Stock Price"
[3,] "Misc Gain" "MTCC Gain" "Gain"
[4,] "Position" "Position" "Position"
[5,] "(4) - (5)" "(3) - (4)" "(6) + (7)"
[6,] "–––––" "–––––" "–––––"
Данные
tx <- c(" Total",
" Total Stock Price",
" Dividend Misc Gain MTCC Gain Gain",
" Proportion Gain Position Position Position",
" Year Dividend Gain Earned (1) x (2) Dividend Gain Misc Gain (4) - (5) (3) - (4) (6) + (7)",
" ––––– ––––– ––––– ––––– ––––– ––––– ––––– ––––– –––––"
)