不使用SAScii库/read.SAScii函数适配NHIS分析代码的方法咨询
核心问题说明
- 你要复现的NHIS数据分析代码里,
read.SAScii的核心作用是三个:从FTP地址下载压缩格式的原始dat数据、自动解压、解析配套SAS脚本里标注的固定宽度列规则,把无分隔符的dat文件读成结构化数据框,最后导出成csv。 - 你目前写的代码有个基础语法错误:
NHISread.in.instructions < ftp://xxx这行缺了赋值符号的后半段,正确写法是<-。另外不能直接用rio::import读这类原始dat文件:这类NHIS公开原始文件是固定宽度格式,没有逗号、制表符这类分隔符,必须靠官方提供的导入脚本指定每一列的起止位置才能正确读入,直接调用import会把所有内容读成乱码。 - 以下给你两个不需要安装SAScii就能实现同等功能的方案,你选一个用就行。
方案1:继续用R实现,不依赖SAScii
你已经装了rio、dplyr这些包,只需要额外装个readr(属于tidyverse系列,基本不会有安装失败的问题),把read.SAScii的逻辑拆成手动步骤写就行,完整可跑代码如下:
# 基础环境配置 setwd("C:/Users/elif/Downloads") library(rio) install_formats() library(dplyr) library(survey) library(readr) # ========== 处理2014年功能残疾数据 ========== # 配置资源地址 nhis_2014_zip <- "ftp://ftp.cdc.gov/pub/Health_Statistics/NCHS/Datasets/NHIS/2014/funcdisb.zip" nhis_2014_sas <- "ftp://ftp.cdc.gov/pub/Health_Statistics/NCHS/Program_Code/NHIS/2014/funcdisb.sas" # 1. 下载文件到临时目录,不用手动存本地占空间 temp_zip <- tempfile(fileext = ".zip") temp_sas_script <- tempfile(fileext = ".sas") download.file(nhis_2014_zip, temp_zip, mode = "wb") download.file(nhis_2014_sas, temp_sas_script) # 2. 解压压缩包拿到dat原始文件 unzip(temp_zip, exdir = tempdir()) dat_file_path <- list.files(tempdir(), pattern = "\\.dat$", full.names = TRUE)[1] # 3. 解析SAS脚本里的列配置 sas_script_lines <- readLines(temp_sas_script) input_block_start <- grep("^\\s*INPUT", sas_script_lines, ignore.case = TRUE)[1] input_block_end <- grep(";", sas_script_lines[input_block_start:length(sas_script_lines)])[1] + input_block_start - 1 input_config <- sas_script_lines[input_block_start:input_block_end] # 清洗提取列名、列位置 config_items <- gsub("^\\s+|\\s+$", "", unlist(strsplit(input_config, "\\s+"))) config_items <- config_items[!grepl("INPUT|;", config_items) & nchar(config_items) > 0] col_names <- gsub("\\$|\\d+-\\d+|\\d+", "", config_items) col_pos_match <- regmatches(config_items, regexpr("\\d+-\\d+", config_items)) col_start_pos <- as.numeric(gsub("-\\d+", "", col_pos_match)) col_end_pos <- as.numeric(gsub("\\d+-", "", col_pos_match)) # 4. 按固定宽度规则读入dat文件 fdb_2014 <- read_fwf( file = dat_file_path, col_positions = fwf_positions(start = col_start_pos, end = col_end_pos, col_names = col_names), show_col_types = FALSE ) # 5. 导出为csv export(fdb_2014, "fdb2014.csv") # ========== 处理2013年功能残疾数据 ========== # 替换成2013年的两个资源地址,重复上面的下载、解压、解析、读入、导出步骤即可 nhis_2013_zip <- "ftp://ftp.cdc.gov/pub/Health_Statistics/NCHS/Datasets/NHIS/2013/funcdisb.zip" nhis_2013_sas <- "ftp://ftp.cdc.gov/pub/Health_Statistics/NCHS/Program_Code/NHIS/2013/funcdisb.sas"
方案2:转成Stata do文件实现
CDC官方本来就提供了对应年份的Stata格式导入do文件,逻辑比R更简单,你不用自己写解析逻辑,直接补全下载解压步骤就行,do文件代码如下:
* 设置工作路径 cd "C:/Users/elif/Downloads" * ========== 处理2014年数据 ========== * 下载数据压缩包和官方导入do文件 copy "ftp://ftp.cdc.gov/pub/Health_Statistics/NCHS/Datasets/NHIS/2014/funcdisb.zip" "funcdisb2014.zip", replace copy "ftp://ftp.cdc.gov/pub/Health_Statistics/NCHS/Program_Code/NHIS/2014/funcdisb.do" "funcdisb2014.do", replace * 解压压缩包得到dat文件 unzipfile "funcdisb2014.zip", replace * 打开下载好的funcdisb2014.do文件,把里面引用dat文件的路径改成你本地解压后的dat文件路径,保存后运行 do "funcdisb2014.do" * 导出为csv格式 export delimited using "fdb2014.csv", replace * ========== 2013年数据替换对应资源地址,重复上述步骤即可 ==========
新手提示:如果跑上面的解析代码出问题,不用硬debug,直接手动把zip压缩包和对应SAS/Stata导入脚本下载到本地,解压出dat文件后:
- 用R的话,在RStudio右上角点「Import Dataset」→「Import Fixed Width Text」,选解压好的dat文件,对照导入脚本里列的位置、名称手动配置,点导入后会自动生成正确的读入代码
- 用Stata的话,直接打开官方下的do文件改好dat路径,点运行就能完成导入
内容的提问来源于stack exchange,提问作者Elif
相关产品推荐
相关产品推荐

