R - 如何提取字符串和空行之间的文本?

R - How to extract text between string and blank line?

我正在使用readLines读取以下文本文件的内容:

*--------------------------------------------------------------------*
* 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 中执行此操作的简便方法是什么?谢谢。

获取"LAI_OBS"的索引(貌似==可以用于case,如果不是固定大小写,那么grep更有用。然后,获取nzchar的空白元素的索引,select第一个大于'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

据我所知,关于输入文件的棘手部分是能够清楚地表达输入数据的结束位置。一种方法是继续沿着当前路径前进并再次使用 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 模拟。

这可行,虽然不优雅但可以完成工作:

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

中获取第一个