2016-12-21 6 views
2

Я использую readLines, чтобы прочитать содержимое следующего текстового файла:R - Как извлечь текст между строкой и пустой линией?

*--------------------------------------------------------------------* 
* 7. Measured data             * 
* And option to force measured LAI during simulation    * 
* (instead of using simulated values)        * 
*--------------------------------------------------------------------* 
* Observed phenology: only required if program DRATES is run!! 
IDOYTR = 194 ! Day of transplanting (give 0 if direct-seeded) 
IYRTR = 1991 ! Year of transplanting (give 0 if direct-seeded) 
IDOYPI = 240 ! Day of panicle initiation (give -99 if not observed) 
IYRPI = 1991 ! Year of panicle initiation (give -99 if not observed) 
IDOYFL = 260 ! Day of flowering 
IYRFL = 1991 ! Year of flowering 
IDOYM = 288 ! Day of maturity 
IYRM = 1991 ! Year of maturity 


*Leaf Area Index (m2 leaf/m2 ground): 
LAI_OBS = 
1991., 182., 0.00 , 
1991., 194., 0.028, 
1991., 202., 0.185, 
1991., 211., 0.325, 
1991., 219., 1.048, 
1991., 240., 3.680, 
1991., 254., 5.010, 
1991., 260., 4.628, 
1991., 273., 3.520, 
1991., 288., 1.938 

*-- Parameter to set forcing of observed LAI during simulation 
LAI_FRC = 0  ! No forcing 
*LAI_FRC = 2  ! Forcing 

И мне нужно программно извлечь только блок текста, идентифицированного LAI_OBS =. Номер строки, где находится LAI_OBS =, отличается от файла к файлу. Поэтому мне нужно найти способ прочитать весь текст между строкой LAI_OBS = и следующей пустой строкой.

До сих пор я использую:

l <- readLines('file.txt') 
which(obs.lai=='LAI_OBS =') 

я могу определить начальную строку блока, мне нужно извлечь, но я не знаю, как поручить R, чтобы перейти к первой пустой строке после LAI_OBS = ,

В результате мне нужно это кадр данных вида:

1991 182 0.00 
1991 194 0.028 
1991 202 0.185 
1991 211 0.325 
1991 219 1.048 
1991 240 3.680 
1991 254 5.010 
1991 260 4.628 
1991 273 3.520 
1991 288 1.938 

Что это удобный способ сделать это в R? Благодарю.

ответ

3

Получить индекс «LAI_OBS» (он выглядит как == может быть использован для в случае, если это не фиксированный случай, то grep полезнее. Тогда, получить индекс чистых элементов с nzchar, выберите первый пустой индекс, который больше, чем «i1», получим последовательность из «i1» до «i2» (после внесения корректировок, т.е. добавления 1 и вычитанием 1), удалить лишние символы, используя sub/gsub и читать с read.csv

i1 <- grep("LAI_OBS =", l)+1 
i2 <- which(!nzchar(l)) 
i3 <- i2[i2>i1][1]-1  
read.csv(text=gsub("\\.,", ",", sub("\\s*,$", "", l[i1:i3])), header=FALSE) 
# V1 V2 V3 
#1 1991 182 0.000 
#2 1991 194 0.028 
#3 1991 202 0.185 
#4 1991 211 0.325 
#5 1991 219 1.048 
#6 1991 240 3.680 
#7 1991 254 5.010 
#8 1991 260 4.628 
#9 1991 273 3.520 
#10 1991 288 1.938 
+0

Спасибо @akrun, yo Ур вклад в это сообщество удивительно! – thiagoveloso

2

Из того, что я собираю, сложная часть вашего входного файла способна формулировать, где заканчиваются входные данные. Один из подходов состоит в том, чтобы продолжить вниз ваш текущий пат ч и использовать which снова, чтобы соответствовать следующей строки:

*-- Parameter to set forcing of observed LAI during simulation 

idx1 <- which(obs.lai=='LAI_OBS =') 
idx2 <- which(substring(obs.lai, 1, 20) == '*-- Parameter to set') 

df.keep <- obs.lai[idx1:idx2-1, ] 

Обратите внимание, что если файл имеет несколько линий, начиная с 20 символов я пытаюсь соответствовать, вы, возможно, придется увеличить длину подстроки. Моя догадка заключается в том, что полная строка будет уникальной, поскольку она относится к моделированию LAI.

1

Это работает, не элегантный, но получает работу:

l <- readLines('data.txt') 
first <- which(l=='LAI_OBS =') 
blanks <- which(l=='') 
whichblank <- which(which(l=='') > first) 
last <- blanks[whichblank] 
first 
last 

выходы:

[1] 18 [1] 29

Конечно, если есть больше пустые строки в файле, которые вы просто возьмете первым из whichblank