【问题标题】:Importing Variable length text files per individual into R将每个人的可变长度文本文件导入R
【发布时间】:2021-09-21 18:11:13
【问题描述】:

我想将一个非常大的文本文件作为数据框导入 R。该文件由比利时的“国家健康和残疾保险研究所”制作,可在此处下载:https://www.riziv.fgov.be/webprd/appl/pDownloadcenter/download/ProductionTXT-Base-Full-2021-07-01.zip。我对 zip 文件感兴趣的文件是“SZVBaseHCW_Full_2021-07-01_ano.txt”。它包含比利时卫生专业人员的个人数据。

这是一个固定宽度的文本文件,我通常用“read_fwf”导入那种数据。问题是文件的结构有点棘手:

  • 单个数据分为八个“类型”(“类型 11”、“类型 12”、“类型 13”等),位于不同的行上。所以每个人都有几行(= 不同类型的信息)。
  • 每一行都以关于这些个人的相同信息的“前缀部分”开始,这允许个人加入数据。因此,对于同一个人,此“前缀部分”会逐行重复。
  • 每个部分(每个“类型”/行和“前缀部分”)都有自己的固定宽度结构。例如,前缀部分有 54 个字符,其中第 53 和 54 个字符表示类型;类型 11 有 249 个字符,分为 18 个变量;类型 12 有 78 个字符,分为 5 个变量;类型 13 有 110 个字符,分为 12 个变量;等
  • 但是,每个人的“类型”数量(以及因此的行数)是可变的。有些人每行有 3 种类型,其他人有 4、5、6、7 或 8 种。这意味着每个人的类型/行数是可变的。

这是一个虚构的结构示例,非常简化。 “前缀部分”是 0000xxx 部分。前 5 个字符表示个人。 “前缀部分”的最后 2 个字符指定行的“类型”。每行包含特定于该“类型”的数据,分为变量(变量的宽度结构在注释中指出):

0000111abaabacd
0000112abbbba
0000113ccaxyzzghj5
0000211acatbacz
0000212zbabba
0000311tyyyuacd
0000312xbbiop
0000411pkggbacz

#type 11 has 3 variables. Width for each : 2,3,3
#type 12 has 2 variables. Width for each : 3,3
#type 13 has 4 variables. Width for each : 3,3,1,4

所以,我想做的是将每个人导入到 R 中的数据框中,并将其导入一个唯一的行,将每种类型的所有变量都导入到单独的列中。如果缺少变量(因为没有类型/行),我想为每个变量指明空数据(NA)。

id     var1  var2  var3  var4  var5  var6  var7  var8  var9
00001    ab   aab   acd   abb   bba   cca   xyz     z  ghj5
00002    ac   atb   acz   zba   bba    NA    NA    NA    NA  
00003    ty   yyu   acd   xbb   iop    NA    NA    NA    NA
00004    pk   ggb   acz    NA    NA    NA    NA    NA    NA

我有点迷茫,我不知道从哪里开始,因为这种结构对我来说真的不常见。你有什么想法或建议吗?

非常感谢!

【问题讨论】:

  • “宽度结构”表示每个“类型”中每个变量的宽度。对不起,很难解释,结构不友好。比较第一个表和第二个表,你就明白了。

标签: r import fixed-width variable-length


【解决方案1】:

假设在最后的注释中可重现地显示输入,将其读取为 3 个字段,然后重新调整为宽格式,每种类型一列。最后将每个此类列中的字段分开。

library(dplyr)
library(readr)
library(tidyr)

cols <- fwf_cols(id = 5, type = 2, misc = NA)

# DF <- read_fwf("myfile", cols)
DF <- read_fwf(Lines, cols)

DF %>%
  pivot_wider(names_from = "type", values_from = "misc") %>%
  separate(`11`, c("var1", "var2", "var3"), cumsum(c(2, 3, 2))) %>%
  separate(`12`, c("var4", "var5"), cumsum(c(3, 3))) %>%
  separate(`13`, c("var6", "var7", "var8", "var9"), cumsum(c(3, 3, 1, 4)))

给予:

# A tibble: 4 x 10
  id    var1  var2  var3  var4  var5  var6  var7  var8  var9 
  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 00001 ab    aab   ac    abb   bba   cca   xyz   z     ghj5 
2 00002 ac    atb   ac    zba   bba   <NA>  <NA>  <NA>  <NA> 
3 00003 ty    yyu   ac    xbb   iop   <NA>  <NA>  <NA>  <NA> 
4 00004 pk    ggb   ac    <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 

注意

Lines <- "0000111abaabacd
0000112abbbba
0000113ccaxyzzghj5
0000211acatbacz
0000212zbabba
0000311tyyyuacd
0000312xbbiop
0000411pkggbacz"

【讨论】:

  • 非常感谢,它启发了我处理完整数据库的理念!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 2023-03-03
相关资源
最近更新 更多