【问题标题】:Import a .dat file from CDC mortality 2003 into Rstudio将 .dat 文件从 CDC 死亡率 2003 导入 Rstudio
【发布时间】:2016-10-25 01:49:39
【问题描述】:

问候 stackoverflow R 社区; 我从 CDC 下载了 10 个数据集,这些数据集对应于 2003 年至 2013 年的死亡率。每一年都是一个单独的数据集。一些数据集的扩展名为 .DUSMCPUB,而另一些数据集的扩展名为 .dat。我在 github 上找到了一个 python 脚本来解析 2013 .DUSMCPUB 文件并将其导出为 .csv。但是,我还没有找到任何可以读取 .dat 文件的内容。我正在使用data <- read.table(file = 'Mort03us.dat', header =TRUE, sep = ',') 玩弄并更改参数。当我在文本编辑器中打开 .dat 文件时,我得到了这个结果。

我期待此数据的标题。但是,我确实阅读了文档以查看值的位置是否对文档有意义,而没有。 我搜索 CDC 网站希望找到有关如何读取文件的文档,或从什么软件导出此文件,或一些可能有助于读取文件的信息,但我没有找到任何文档。 Here 我发现了一个类似的问题,但是,我的 .dat 不是文本,脚本不适合我。另外,我玩弄了这个脚本,但没有成功。

你们中的任何人都使用过 .dat 格式的 CDC 数据集,可以指导我如何将这些数据导入 RStudio?


2016 年 7 月 1 日:

这个问题的解答:

我想更新我的问题。我找到了一个解决方案,我想与社区分享。最后,我从 github 调整了一个 python 脚本。我能够解析 .dat 文件并将数据集导入 R。谢谢大家!

fileObj = open('Mort03us.dat', 'r')
fileOutObj = open('mort_2003.csv', 'a')

fileOutObj.write('Resident_Status, Education, Month_Of_Death, Sex, Age_Key, Age_Value, Age_Sub_Flag, Age_Recode_52, ' +
             'Age_Recode_27, Age_Recode_12, Infant_Age_Recode_22, Place_Of_Death, Marital_Status, DOW_of_Death, ' +
             'Data_Year, Injured_At_Work, Manner_Of_Death, Method_Of_Disposition, Autopsy, Activity_Code, ' +
             'Place_Of_Causal_Injury, ICD10, Cause_Recode_358, Cause_Recode_113, Infant_Cause_Recode_130, ' +
             'Cause_Recode_39, Entity_Axis_Conditions, EAC1, EAC2, EAC3, EAC4, EAC5, EAC6, EAC7, EAC8, EAC9, ' +
             'EAC10, EAC11, EAC12, EAC13, EAC14, EAC15, EAC16, EAC17, EAC18, EAC19, EAC20, '
             'Record_Axis_Conditions, RA1, RA2, RA3, RA4, RA5, RA6, RA7, RA8, RA9, RA10, RA11, RA12, RA13, RA14, ' +
             'RA15, RA16, RA17, RA18, RA19, RA20, Race, Race_Bridged, Race_Imputation, Race_Recode_3, ' +
             'Race_Recode_5, Hispanic_Origin, Hispanic_Origin_Recode\n')

outStr = ''

for line in fileObj:
    Resident_Status = line[19].strip()
    Education = line[60:62].strip()
    Month_Of_Death = line[64:66].strip()
    Sex = line[68].strip()
    Age_Key = line[69].strip()
    Age_Value = line[70:73].strip()
    Age_Sub_Flag = line[73].strip()
    Age_Recode_52 = line[74:76].strip()
    Age_Recode_27 = line[76:78].strip()
    Age_Recode_12 = line[78:80].strip()
    Infant_Age_Recode_22 = line[80:82].strip()
    Place_Of_Death = line[82].strip()
    Marital_Status = line[83].strip()
    DOW_of_Death = line[84].strip()
    Data_Year = line[101:105].strip()
    Injured_At_Work = line[105].strip()
    Manner_Of_Death = line[106].strip()
    Method_Of_Disposition = line[107].strip()
    Autopsy = line[108].strip()
    Activity_Code = line[143].strip()
    Place_Of_Causal_Injury = line[144].strip()
    ICD10 = line[145:149].strip()
    Cause_Recode_358 = line[149:152].strip()
    Cause_Recode_113 = line[153:156].strip()
    Infant_Cause_Recode_130 = line[156:159].strip()
    Cause_Recode_39 = line[159:161].strip()
    Entity_Axis_Conditions = line[162:164].strip()
    EAC1 = line[164:171].strip()
    EAC2 = line[171:178].strip()
    EAC3 = line[178:185].strip()
    EAC4 = line[185:192].strip()
    EAC5 = line[192:199].strip()
    EAC6 = line[199:206].strip()
    EAC7 = line[206:213].strip()
    EAC8 = line[213:220].strip()
    EAC9 = line[220:227].strip()
    EAC10 = line[227:234].strip()
    EAC11 = line[234:241].strip()
    EAC12 = line[241:248].strip()
    EAC13 = line[248:255].strip()
    EAC14 = line[255:262].strip()
    EAC15 = line[262:269].strip()
    EAC16 = line[269:276].strip()
    EAC17 = line[276:283].strip()
    EAC18 = line[283:290].strip()
    EAC19 = line[290:297].strip()
    EAC20 = line[297:304].strip()
    Record_Axis_Conditions = line[340:342]
    RA1 = line[343:348].strip()
    RA2 = line[348:353].strip()
    RA3 = line[353:358].strip()
    RA4 = line[358:363].strip()
    RA5 = line[363:368].strip()
    RA6 = line[368:373].strip()
    RA7 = line[373:378].strip()
    RA8 = line[378:383].strip()
    RA9 = line[383:388].strip()
    RA10 = line[388:393].strip()
    RA11 = line[393:398].strip()
    RA12 = line[398:403].strip()
    RA13 = line[403:408].strip()
    RA14 = line[408:413].strip()
    RA15 = line[413:418].strip()
    RA16 = line[418:423].strip()
    RA17 = line[423:428].strip()
    RA18 = line[428:433].strip()
    RA19 = line[433:438].strip()
    RA20 = line[438:443].strip()
    Race = line[444:446].strip()
    Race_Bridged = line[446].strip()
    Race_Imputation = line[447].strip()
    Race_Recode_3 = line[448].strip()
    Race_Recode_5 = line[449].strip()
    Hispanic_Origin = line[483:486].strip()
    Hispanic_Origin_Recode = line[487].strip()
      
    outStr = (Resident_Status + ', ' + Education + ', ' + Month_Of_Death + ', ' + Sex +
          ', ' + Age_Key + ', ' + Age_Value + ', ' + Age_Sub_Flag + ', ' + Age_Recode_52 +
          ', ' + Age_Recode_27 + ', ' + Age_Recode_12 + ', ' + Infant_Age_Recode_22 + ', ' + Place_Of_Death +
          ', ' + Marital_Status + ', ' + DOW_of_Death + ', ' + Data_Year + ', ' + Injured_At_Work +
          ', ' + Manner_Of_Death + ', ' + Method_Of_Disposition + ', ' + Autopsy + ', ' + Activity_Code +
          ', ' + Place_Of_Causal_Injury + ', ' + ICD10 + ', ' + Cause_Recode_358 + ', ' + Cause_Recode_113 +
          ', ' + Infant_Cause_Recode_130 + ', ' + Cause_Recode_39 + ', ' + Entity_Axis_Conditions + ', ' + EAC1 +
          ', ' + EAC2 + ', ' + EAC3 + ', ' + EAC4 + ', ' + EAC5 +
          ', ' + EAC6 + ', ' + EAC7 + ', ' + EAC8 + ', ' + EAC9 +
          ', ' + EAC10 + ', ' + EAC11 + ', ' + EAC12 + ', ' + EAC13 +
          ', ' + EAC14 + ', ' + EAC15 + ', ' + EAC16 + ', ' + EAC17 +
          ', ' + EAC18 + ', ' + EAC19 + ', ' + EAC20 + ', ' + Record_Axis_Conditions +
          ', ' + RA1 + ', ' + RA2 + ', ' + RA3 + ', ' + RA4 +
          ', ' + RA5 + ', ' + RA6 + ', ' + RA7 + ', ' + RA8 +
          ', ' + RA9 + ', ' + RA10 + ', ' + RA11 + ', ' + RA12 +
          ', ' + RA13 + ', ' + RA14 + ', ' + RA15 + ', ' + RA16 +
          ', ' + RA17 + ', ' + RA18 + ', ' + RA19 + ', ' + RA20 +
          ', ' + Race + ', ' + Race_Bridged + ', ' + Race_Imputation + ', ' + Race_Recode_3 +
          ', ' + Race_Recode_5 + ', ' + Hispanic_Origin + ', ' + Hispanic_Origin_Recode + '\n')

fileOutObj.write(outStr)

print("Parse complete.")
fileOutObj.close()
fileObj.close()

此代码适用于 Python 3。

【问题讨论】:

  • 您能张贴一小部分文件或指向它的链接吗?图片没有帮助
  • 您的 .dat 文件图像在我看来就像所有文本,在这种情况下,read.fwf 或某种形式的正则表达式应该能够导入它。
  • 链接是here。请注意,您需要Morality Multiple Cause Files。请下载 2003 压缩文件。 @r2evans - 我以前处理过 CDC 数据,但这张图片没有显示 CDC 通常构建数据集的方式。
  • 您询问了您正在显示的 this 文件,当我刚刚下载它时,该文件 文本 (Mort03ps.dat: ASCII text, with very long lines, with CRLF line terminators)。阅读?read.fwf。 (或提供有关不同格式文件的信息。)
  • 您可以通过WONDER获取CSV

标签: r import dataset


【解决方案1】:

无论文件扩展名如何,它都只是一个文本文件(88MB,240 万行)。经检查,它看起来是固定宽度的(430 个字符宽,此处显示有点宽,尽管您的图片确实如此)。

读取 FWF 文件的唯一“技巧”是查找列宽。在某些“dat”文件中,这是明确定义/记录的,但通常可以通过查看前几行来推断。在这种情况下,我只计算字符。 (为简洁起见,我只抓取前 100 行。)

某些字段似乎是用空格分隔的。也就是说,一些(甚至大多数)行在两个分组之间有一个空格,但有些行没有。由于我不知道如何解码逻辑,我将它们放在一起(与空间)。 (即:V6V8V9。)

mort <- read.fwf("~/Downloads/foo/Mort03us.dat",
                 widths = c(30, 26, 6, 4, 7, 12, 24, 43, 9, 178, 3, 100, 4, 4, 36, 2),
                 header = FALSE, n = 100, stringsAsFactors = FALSE)
str(mort)
# 'data.frame': 100 obs. of  16 variables:
#  $ V1 : chr  "                  11AK999AK9AK" "                  11AK999AK9AK" "                  11AK999AK9AK" "                  11AK999AK9AK" ...
#  $ V2 : chr  "  AK9999999992AK00009900OR" "  AK9999999992AK00009900NY" "  AK9999999992AK00009900WA" "  AK9999999992AK00009900TX" ...
#  $ V3 : chr  "  OR14" "  NY17" "  WA15" "  TX16" ...
#  $ V4 : int  1 1 1 1 1 1 1 1 1 1 ...
#  $ V5 : chr  "  F1079" "  F1088" "  F1059" "  F1084" ...
#  $ V6 : chr  " 412110  4W4" " 432311  1W6" " 371708  6D7" " 422210  4W7" ...
#  $ V7 : chr  "                2003U7UN" "                2003U7UN" "                2003U7UN" "                2003U7UN" ...
#  $ V8 : chr  "                                    I361226" "                                    I499228" "                                    C64 117" "                                    C349093" ...
#  $ V9 : chr  " 068   22" " 068   22" " 034   12" " 027   08" ...
#  $ V10: chr  " 0711I500 21I361 31I10  61I679 62I739 63M199 64N289                                                                            "| __truncated__ " 0311R568 21I959 31I499                                                                                                        "| __truncated__ " 0111C64                                                                                                                       "| __truncated__ " 0111C349                                                                                                                      "| __truncated__ ...
#  $ V11: int  7 3 1 1 2 3 4 4 1 1 ...
#  $ V12: chr  " I10  I361 I500 I679 I739 M199 N289                                                                 " " I499 I959 R568                                                                                     " " C64                                                                                                " " C349                                                                                               " ...
#  $ V13: int  1 1 1 3 3 1 1 1 1 1 ...
#  $ V14: int  11 11 11 23 23 11 11 11 11 11 ...
#  $ V15: int  100 100 100 100 100 100 100 100 100 100 ...
#  $ V16: int  6 6 6 8 8 6 6 6 6 6 ...

有很多空白,read.fwf 函数不会自动为您删除它,所以接下来我们必须处理它。

# chars <- sapply(mort, is.character)
mort[,chars] <- sapply(mort[,chars], function(z) {
  gsub("[[:space:]]+", " ", trimws(z))
}, simplify = FALSE)
str(mort)
# 'data.frame': 100 obs. of  16 variables:
#  $ V1 : chr  "11AK999AK9AK" "11AK999AK9AK" "11AK999AK9AK" "11AK999AK9AK" ...
#  $ V2 : chr  "AK9999999992AK00009900OR" "AK9999999992AK00009900NY" "AK9999999992AK00009900WA" "AK9999999992AK00009900TX" ...
#  $ V3 : chr  "OR14" "NY17" "WA15" "TX16" ...
#  $ V4 : int  1 1 1 1 1 1 1 1 1 1 ...
#  $ V5 : chr  "F1079" "F1088" "F1059" "F1084" ...
#  $ V6 : chr  "412110 4W4" "432311 1W6" "371708 6D7" "422210 4W7" ...
#  $ V7 : chr  "2003U7UN" "2003U7UN" "2003U7UN" "2003U7UN" ...
#  $ V8 : chr  "I361226" "I499228" "C64 117" "C349093" ...
#  $ V9 : chr  "068 22" "068 22" "034 12" "027 08" ...
#  $ V10: chr  "0711I500 21I361 31I10 61I679 62I739 63M199 64N289" "0311R568 21I959 31I499" "0111C64" "0111C349" ...
#  $ V11: int  7 3 1 1 2 3 4 4 1 1 ...
#  $ V12: chr  "I10 I361 I500 I679 I739 M199 N289" "I499 I959 R568" "C64" "C349" ...
#  $ V13: int  1 1 1 3 3 1 1 1 1 1 ...
#  $ V14: int  11 11 11 23 23 11 11 11 11 11 ...
#  $ V15: int  100 100 100 100 100 100 100 100 100 100 ...
#  $ V16: int  6 6 6 8 8 6 6 6 6 6 ...

最后一点要考虑的是,一些 uber-wide 字段(V10V12)似乎是代码的变量列表。由于我不确定自己确切地知道有多少等,所以我也选择将它们放在一起。 (这是了解更多 Hadley 包的好时机,特别是 broompurrrThis youtube video 是 Hadley 谈论使用这些包的嵌套数据帧的一个小时。)

(为了记录,加载整个文件并执行此处理确实需要一段时间,所以请耐心等待。我的建议是在整个文件的一个适度子集上“练习”,以确保您的处理正在执行你想要的。当你规划好你的步骤并进行测试后,然后把它们全部运行起来,去喝杯咖啡。)

【讨论】:

  • 您需要先了解数据的含义,然后再执行您所做的操作。根据文档,前 18 个空格或位置是保留位置。 $V1 = "11AK999AK9AK",长度为 12 个字符,第 1 位 1 表示记录类型。第二个1 表示居民身份。第 3 和第 4 位 AK 是发生状态。整个字符串不是一个值。我无法按照您的方式导入数据。有些位置对于某些观察是空的,但对于其他观察有数据。数据需要在导入 R 之前进行解析。
  • 可能只需要调整字段宽度(即将最初的 30 个字符字段拆分为 19(18 个空格 + 第一个位置 [记录类型])、1(居民身份)、2(状态),3(?),2(再次状态),1(?),2(再次状态)。
  • 谢谢@BenBolker,是的,这就是目的:展示如何进行基本导入,以便吉尔伯特可以根据文件格式根据需要更改它。我确信我的一些假设是错误的,但话又说回来,一旦你知道什么是错误的以及它是如何完成的,纠正它应该是相当容易的。
  • 我正在使用 python 脚本来解析整个 .dat 文件,然后再导入 R。由于英语不是我的第一语言,我的问题可能不清楚。我希望你们中的任何人都知道解析 .dat 文件的脚本。不过我差不多完成了。我将发布我的工作以帮助他人。
  • 你的英语没问题。我很困惑您要求 in R 的解决方案,我提供的解决方案 很容易 调整以适应不同的列宽,@alistaire 建议了一个网站已经解析了 CSV,但您对所有这些都打了折扣。做你想做的。
猜你喜欢
  • 2015-11-27
  • 2012-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-30
  • 1970-01-01
  • 2017-09-07
  • 1970-01-01
相关资源
最近更新 更多