Как правильно разбить строку в соответствии с ее расположением в R? - PullRequest
0 голосов
/ 25 апреля 2019

Мне дан вектор строк, как показано ниже:

t1 <- "                                                                                                                Total"     
t2 <- "                                          Total                                                              Stock Price"  
t3 <- "                                         Dividend                              Misc Gain      MTCC Gain         Gain"      
t4 <- "                         Proportion        Gain                                Position        Position       Position"    
t5 <- "   Year   Dividend Gain    Earned        (1) x (2)   Dividend Gain Misc Gain    (4) - (5)       (3) - (4)     (6) + (7)"   
t6 <- "  –––––        –––––        –––––          –––––         –––––       –––––        –––––          –––––          –––––"     
t  <- c(t1, t2, t3, t4, t5, t6)

Из приведенного выше видно, что заголовок таблицы выровнен по центру последнего элемента t6 .

Теперь я пытаюсь получить начальный и конечный индексы самого длинного слова в каждом столбце, описанном выше.

Например, столбец 3 -

 Proportion 
   Earned   
    –––––    

Самое длинное слово - Proportion, тогда я попытаюсь найти начальный и конечный индекс Proportion в t4 .

Другой пример для столбца 2

Dividend Gain
     –––––   

Самое длинное слово (а) - Dividend Gain, я попытаюсь найти начальный и конечный индекс Dividend Gain в t5 .

Как мне найти нужный мне индекс из t ?

1 Ответ

2 голосов
/ 25 апреля 2019

Одним из решений может быть сопоставление позиций символов всех векторов.

Во-первых, может быть полезно, если все строки имеют одинаковое количество символов.Мы можем достичь этого, добавив немного пробела в конце.

# 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)", 
"  –––––        –––––        –––––          –––––         –––––       –––––        –––––          –––––          –––––"
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...