извлекать повторяющиеся линии / шаблоны в текстовом файле в R - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть длинный текстовый файл (txt), который я извлек, используя readLines(). У него повторяющийся паттерн, но меня интересуют только некоторые конкретные строки c. Вот краткая версия моего файла:

[1] "Set            1"                                              
[2] "DVRJ, DVRI, DVRP, DVRR !Parameters"           
[3] "DVRJ = 0.0012150"                                                   
[4] "DVRI = 0.0007576"                                                   
[5] "DVRP = 0.0006010"                                                   
[6] "DVRR = 0.0020851"                                                   
[7] "TSTR, TSPI, TSF,  TSM  !Temperature"           
[8] "        0.00,      659.22,     1241.55,     1721.16"                
[9] "TGDDTR,TGDDPI,TGDDF,TGDDM  !GDD above TBD"            
[10] "        0.00,      660.52,     1246.67,     1726.62"                
[11] "DASTR , DASPI , DASF  , DASM  !Duration"
[12] "        0.00,       35.00,       70.00,      100.00"                
[13] "Set            2"                                              
[14] "DVRJ, DVRI, DVRP, DVRR !Parameters"           
[15] "DVRJ = 0.0012713"                                                   
[16] "DVRI = 0.0007576"                                                   
[17] "DVRP = 0.0005982"                                                   
[18] "DVRR = 0.0021067"                                                   
[19] "TSTR, TSPI, TSF,  TSM  !Temperature"           
[20] "        0.00,      644.65,     1229.76,     1704.44"                
[21] "TGDDTR,TGDDPI,TGDDF,TGDDM  !GDD above TBD"            
[22] "        0.00,      645.42,     1234.33,     1711.56"                
[23] "DASTR , DASPI , DASF  , DASM  !Duration"
[24] "        0.00,       35.00,       70.00,      100.00"                
[25] "Set            3"                                              
[26] "DVRJ, DVRI, DVRP, DVRR !Parameters"           
[27] "DVRJ = 0.0012713"                                                   
[28] "DVRI = 0.0007576"                                                   
[29] "DVRP = 0.0005982"                                                   
[30] "DVRR = 0.0021067"                                                   
[31] "TSTR, TSPI, TSF,  TSM  !Temperature"           
[32] "        0.00,      644.65,     1229.76,     1704.44"                
[33] "TGDDTR,TGDDPI,TGDDF,TGDDM  !GDD above TBD"            
[34] "        0.00,      645.42,     1234.33,     1711.56"                
[35] "DASTR , DASPI , DASF  , DASM  !Duration"
[36] "        0.00,       35.00,       70.00,      100.00" 

Я только хочу получить:

Set *value*                                                      
DVRJ = *value*                                                 
DVRI = *value*                                                  
DVRP = *value*                                                  
DVRR = *value*

После этого я хотел бы повернуть результаты, чтобы создать фрейм данных, который выглядит как this:

  Set      DVRJ    DVRI     DVRP    DVRR
*value*  *value*  *value*  *value*  *value*
*value*  *value*  *value*  *value*  *value*
*value*  *value*  *value*  *value*  *value*

Сначала я попытался использовать strsplit(), чтобы убрать ненужные мне строки:

strsplit(txt, split = c("DVRJ, DVRI, DVRP, DVRR !Parameters",
                        "TSTR, TSPI, TSF,  TSM  !Temperature",
                        "TGDDTR,TGDDPI,TGDDF,TGDDM  !GDD above TBD",
                        "DASTR , DASPI , DASF  , DASM  !Duration"
                        ))

Мало того, что это не сработало, но и не будет устранять их соответствующие значения. Я ценю любую помощь. Спасибо!

Ответы [ 2 ]

2 голосов
/ 22 апреля 2020

Мы можем использовать:

library(dplyr)
library(tidyr)
#Select only specific lines which follows a pattern
data.frame(col = grep('(Set\\s+\\d+)|((DVRJ|DVRI|DVRP|DVRR)\\s+=)', 
                 lines, value = TRUE), stringsAsFactors = FALSE) %>%
   #Add same separator to "Set" as rest of data i.e "="
   mutate(col = ifelse(startsWith(col, 'Set'), gsub('\\s+', ' = ', col), col)) %>%
   #Divide data into different columns based on sep
   separate(col, c('col', 'value'), sep = " = ", convert = TRUE) %>%
   group_by(col) %>%
   #Create a unique index column
   mutate(Row = row_number()) %>%
   #Get data in wide format. 
   pivot_wider(names_from = col, values_from = value) %>%
   select(-Row)


# A tibble: 2 x 5
#    Set    DVRJ     DVRI     DVRP    DVRR
#  <dbl>   <dbl>    <dbl>    <dbl>   <dbl>
#1     1 0.00122 0.000758 0.000601 0.00209
#2     2 0.00127 0.000758 0.000598 0.00211

, где lines равно

lines <- c("Set            1", "DVRJ, DVRI, DVRP, DVRR !Parameters", 
"DVRJ = 0.0012150", "DVRI = 0.0007576", "DVRP = 0.0006010", "DVRR = 0.0020851", 
"TSTR, TSPI, TSF,  TSM  !Temperature", "        0.00,      659.22,     1241.55,     1721.16", 
"TGDDTR,TGDDPI,TGDDF,TGDDM  !GDD above TBD", "        0.00,      660.52,     1246.67,     1726.62", 
"DASTR , DASPI , DASF  , DASM  !Duration", "        0.00,       35.00,       70.00,      100.00", 
"Set            2", "DVRJ, DVRI, DVRP, DVRR !Parameters", "DVRJ = 0.0012713", "DVRI = 0.0007576", 
"DVRP = 0.0005982", "DVRR = 0.0021067")
1 голос
/ 22 апреля 2020

Вот решение на основе Base R с фиксированными полями записи. Мы используем read.fwf() для чтения нескольких записей ввода, анализируя необходимые данные в строках 1, 3, 4, 5 и 6.

Сначала мы преобразуем входные данные из OP в R объект, чтобы сделать пример воспроизводимым.

fixedText = "Set            1                                             
DVRJ, DVRI, DVRP, DVRR !Parameters                  
DVRJ = 0.0012150                                                  
DVRI = 0.0007576                                                  
DVRP = 0.0006010                                                  
DVRR = 0.0020851                                                  
TSTR, TSPI, TSF,  TSM  !Temperature                 
        0.00,      659.22,     1241.55,     1721.16               
TGDDTR,TGDDPI,TGDDF,TGDDM  !GDD above TBD           
        0.00,      660.52,     1246.67,     1726.62               
DASTR , DASPI , DASF  , DASM  !Duration             
        0.00,       35.00,       70.00,      100.00               
Set            2                                             
DVRJ, DVRI, DVRP, DVRR !Parameters                  
DVRJ = 0.0012713                                                  
DVRI = 0.0007576                                                  
DVRP = 0.0005982                                                  
DVRR = 0.0021067                                                  
TSTR, TSPI, TSF,  TSM  !Temperature                 
        0.00,      644.65,     1229.76,     1704.44               
TGDDTR,TGDDPI,TGDDF,TGDDM  !GDD above TBD           
        0.00,      645.42,     1234.33,     1711.56               
DASTR , DASPI , DASF  , DASM  !Duration             
        0.00,       35.00,       70.00,      100.00               
Set            3                                             
DVRJ, DVRI, DVRP, DVRR !Parameters                  
DVRJ = 0.0012713                                                  
DVRI = 0.0007576                                                  
DVRP = 0.0005982                                                  
DVRR = 0.0021067                                                  
TSTR, TSPI, TSF,  TSM  !Temperature                 
        0.00,      644.65,     1229.76,     1704.44               
TGDDTR,TGDDPI,TGDDF,TGDDM  !GDD above TBD           
        0.00,      645.42,     1234.33,     1711.56               
DASTR , DASPI , DASF  , DASM  !Duration             
        0.00,       35.00,       70.00,      100.00   
"

Далее мы устанавливаем объекты, требуемые в качестве аргументов, для read.fwf(), включая список «ширин» для чтения данных из 12 строк в файле наблюдения. Отрицательные числа в списке представляют данные, которые не сохранены во фрейме выходных данных.

widthList <- list(c(-14,3,-45),
               c(-50),
               c(-7,9,-50),
               c(-7,9,-50),
               c(-7,9,-50),
               c(-7,9,-50),
               c(-50),
               c(-50),
               c(-50),
               c(-50),
               c(-50),
               c(-50))
theNames <- c("Set","DVRJ", "DVRI", "DVRP", "DVRR")

Наконец, мы запускаем read.fwf(), включая аргументы.

options(sicken = 10) # so we can see the 7th decimal place in data
data <- read.fwf(textConnection(fixedText), widths = widthList,
                 flush=TRUE,col.names = theNames)

... и вывод:

> data
  Set      DVRJ      DVRI      DVRP      DVRR
1   1 0.0012150 0.0007576 0.0006010 0.0020851
2   2 0.0012713 0.0007576 0.0005982 0.0021067
3   3 0.0012713 0.0007576 0.0005982 0.0021067
> 
...