【问题标题】:Handling blocked data in R处理 R 中的阻塞数据
【发布时间】:2018-05-13 23:04:29
【问题描述】:

我有一个来自 WISE 土壤数据库的土壤数据的大文本文件(位于此处https://www.dropbox.com/s/k2jqbpgtxw7d66m/test.txt?dl=0),有点混乱,我需要从中提取一些信息。

文本文件被组织在一些由空行分隔的组中,每个组都遵循如下图所示的相同结构:

*WI_CLAF001  WISE        L       150 WISE DATABASE, SOIL AF001
@SITE        COUNTRY          LAT     LONG SCS Family
 -99         Afganistan    34.500   69.167 Luvic Calcisol (CLl)
@ SCOM  SALB  SLU1  SLDR  SLRO  SLNF  SLPF  SMHB  SMPX  SMKE
    BN  0.13  9.60  0.60 75.00  1.00  1.00 SA001 SA001 SA001
@  SLB  SLMH  SLLL  SDUL  SSAT  SRGF  SSKS  SBDM  SLOC  SLCL  SLSI  SLCF  SLNI  SLHW  SLHB  SCEC  SADC
    15     - 0.129 0.283 0.459  1.00  1.56  1.35  0.76 20.00 40.00 20.00  0.06  7.90 -99.0 -99.0 -99.0
    60     - 0.184 0.327 0.466  0.47  0.69  1.37  0.23 35.00 55.00 -99.0  0.03  7.90 -99.0 -99.0 -99.0
   150     - 0.178 0.311 0.461  0.12  0.87  1.39  0.09 35.00 55.00 -99.0  0.03  7.90 -99.0 -99.0 -99.0
@  SLB  SLPX  SLPT  SLPO CACO3  SLAL  SLFE  SLMN  SLBS  SLPA  SLPB  SLKE  SLMG  SLNA  SLSU  SLEC  SLCA
    15 -99.0 -99.0 -99.0   9.3 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0   0.4 -99.0
    60 -99.0 -99.0 -99.0  17.7 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0   0.3 -99.0
   150 -99.0 -99.0 -99.0  18.2 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0   0.3 -99.0

*WI_FLAF002  WISE        L       170 WISE DATABASE, SOIL AF002
@SITE        COUNTRY          LAT     LONG SCS Family
 -99         Afganistan    34.500   69.000 Calcaric Fluvisol (FLc)
@ SCOM  SALB  SLU1  SLDR  SLRO  SLNF  SLPF  SMHB  SMPX  SMKE
    BN  0.13  9.60  0.25 75.00  1.00  1.00 SA001 SA001 SA001
@  SLB  SLMH  SLLL  SDUL  SSAT  SRGF  SSKS  SBDM  SLOC  SLCL  SLSI  SLCF  SLNI  SLHW  SLHB  SCEC  SADC
    20     - 0.136 0.312 0.477  0.82  1.17  1.29  1.28 20.00 40.00 -99.0  0.09  8.50 -99.0 -99.0 -99.0
    60     - 0.110 0.235 0.502  0.45  4.84  1.24  0.60 20.00 65.00 -99.0  0.06  8.60 -99.0 -99.0 -99.0
   110     - 0.210 0.344 0.472  0.18  0.53  1.35  0.39 35.00 55.00 -99.0  0.06  8.50 -99.0 -99.0 -99.0
   170     - 0.115 0.268 0.441  0.06  1.68  1.41  0.27 20.00 40.00 -99.0  0.03  8.80 -99.0 -99.0 -99.0
@  SLB  SLPX  SLPT  SLPO CACO3  SLAL  SLFE  SLMN  SLBS  SLPA  SLPB  SLKE  SLMG  SLNA  SLSU  SLEC  SLCA
    20 -99.0 -99.0 -99.0  19.1 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0   0.4 -99.0
    60 -99.0 -99.0 -99.0  19.2 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0   0.3 -99.0
   110 -99.0 -99.0 -99.0  20.3 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0   0.3 -99.0
   170 -99.0 -99.0 -99.0  24.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0   0.3 -99.0

*WI_FLAF003  WISE        L       110 WISE DATABASE, SOIL AF003
@SITE        COUNTRY          LAT     LONG SCS Family
 -99         Afganistan    34.500   69.167 Calcaric Fluvisol (FLc)
@ SCOM  SALB  SLU1  SLDR  SLRO  SLNF  SLPF  SMHB  SMPX  SMKE
    BN  0.13  9.60  0.05 75.00  1.00  1.00 SA001 SA001 SA001
@  SLB  SLMH  SLLL  SDUL  SSAT  SRGF  SSKS  SBDM  SLOC  SLCL  SLSI  SLCF  SLNI  SLHW  SLHB  SCEC  SADC
    20     A 0.106 0.276 0.453  0.82  1.66  1.37  0.59 20.00 40.00 -99.0  0.07  8.80 -99.0 -99.0 -99.0
    50    Bg 0.135 0.238 0.404  0.50  2.14  1.49  0.24 10.00 25.00 -99.0  0.04  9.20 -99.0 -99.0 -99.0
   110    Cg 0.081 0.214 0.428  0.20  3.86  1.46 -99.0 25.00 15.00 -99.0 -99.0  8.90 -99.0 -99.0 -99.0
@  SLB  SLPX  SLPT  SLPO CACO3  SLAL  SLFE  SLMN  SLBS  SLPA  SLPB  SLKE  SLMG  SLNA  SLSU  SLEC  SLCA
    20 -99.0 -99.0 -99.0  16.9 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0   1.9 -99.0
    50 -99.0 -99.0 -99.0  13.8 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0   0.6 -99.0
   110 -99.0 -99.0 -99.0  19.6 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0   0.4 -99.0

第 1 行:*WI_... 有一些详细信息。对我没用

第 2 行:包含国家名称、纬度、经度等标题

第 3 行:包含这些标题的数据

第 4 行:另一组标题

第 5 行:包含第 4 行中标题的数据

第 6 行:包含标题

第 7:9 行:包含第 6 行的数据

第 10 行:是第 6 行标题的延续

第 11:13 行:包含第 10 行的数据

问题是,如果您移动到其他一些数据组(不同的国家/地区),第 6 行的行数会发生变化

我正在尝试为每个组做两件事:

1) 第 2 行到第 5 行有一个单独的数据框,如下所示:

  COUNTRY   LAT LONG SCS Family SCOM SALB SLU1 SLDR SLRO SLNF SLPF SMHB SMPX SMKE 
  Afghanistan
  Afghanistan
  Afghanistan
  .
  .
  .
  Argentina
  Argentina
  Argentina
  .
  .
  .

2) 第 6 行到第 N 行的单独数据框

  COUNTRY     LAT       LONG    SLB  SLMH  SLLL  SDUL  SSAT  SRGF  SSKS  SBDM  SLOC  SLCL  SLSI  SLCF  SLNI  SLHW  SLHB  SCEC  SADC  SLPX  SLPT  SLPO CACO3  SLAL  SLFE  SLMN  SLBS  SLPA  SLPB  SLKE  SLMG  SLNA  SLSU  SLEC  SLCA
  Afganistan  34.500   69.167   15
  Afganistan  34.500   69.167   60
  Afganistan  34.500   69.167   150

我以前没有处理过这种类型的数据,但这里有一些我将如何实现这一点的逻辑:

对于 1) 部分,我可以读取数据:

  dat <- readLines("dat.txt")

删除其中包含“WISE”的行。这是多余的行 然后使用空格将数据拆分为列表
R split text on empty line

对于列表的每个元素(组):取第 2 - 5 行并转换为我想要的格式。

对于问题的第二部分,我不确定从第 6 行开始我应该怎么做。

我会很感激这方面的帮助。非常感谢你。

【问题讨论】:

  • 对于第 2 部分,使用 grep 识别以 "@SITE" 开头的行,加 1,然后读取带有 read.table( ,nrows=1,header=TRUE) 的行。然后cbind 会导致从紧跟在“@ SCOM”之后的单行中读取的结果。对于第 3 部分:将 read.table 与 nrows=3 一起使用。

标签: r text scanf


【解决方案1】:

我将代替您的图片插入的文本复制到命名字符变量txt,然后:

tL <- readLines(textConnection(txt))
Site_lines=grep("@SITE",tL)
Site_lines
#[1]  2 16 32
lapply( Site_lines , function(L) read.table(text= tL, header=TRUE, skip=L-1, nrow=1) )
#-----------------------
[[1]]
        X.SITE COUNTRY    LAT  LONG      SCS Family
-99 Afganistan    34.5 69.167 Luvic Calcisol  (CLl)

[[2]]
        X.SITE COUNTRY LAT     LONG      SCS Family
-99 Afganistan    34.5  69 Calcaric Fluvisol  (FLc)

[[3]]
        X.SITE COUNTRY    LAT     LONG      SCS Family
-99 Afganistan    34.5 69.167 Calcaric Fluvisol  (FLc)
# ------- now something that can pull them together ---------
do.call("rbind", lapply( Site_lines , function(L) read.table(text= tL, header=TRUE, skip=L-1, nrow=1) ) )

         X.SITE COUNTRY    LAT     LONG      SCS Family
-99  Afganistan    34.5 69.167    Luvic Calcisol  (CLl)
-991 Afganistan    34.5 69.000 Calcaric Fluvisol  (FLc)
-992 Afganistan    34.5 69.167 Calcaric Fluvisol  (FLc)

不幸的是,该表并不像乍一看那样是常规的。如果您查看完整文件(将近 60,000 行)中“@SITE”位置的间距,您会得到:

table(diff(Site_lines))

 10  12  14  16  18  20  22  24  26 
 47 156 526 664 797 906 169  85  53 

并尝试使用 lapply( ,... read.table 方法会导致错误。您可能需要使用带有tryfor 循环。第一个错误在第 6070 行:

counter <- 0
do.call("rbind", lapply( Site_lines , function(L) { counter <<- L; read.table(text= tL, header=TRUE, skip=L-1, nrow=1) }))
Error in read.table(text = tL, header = TRUE, skip = L - 1, nrow = 1) : 
  more columns than column names
> counter
[1] 6070

【讨论】:

    猜你喜欢
    • 2013-05-15
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 2013-09-08
    • 2013-11-29
    • 2014-07-01
    • 1970-01-01
    相关资源
    最近更新 更多