如何将SEER数据的SAS加载文件转换为R加载命令?
把SEER数据的SAS加载脚本转换为R读取命令
我之前处理过好多SEER数据从SAS转R的需求,这种情况太常见了,咱们一步步来搞定它!
首先先拆解你给的SAS脚本里的关键信息:
filename seer9 './yr1973_2015.seer9/*.TXT';:指定要读取目标目录下所有TXT格式的SEER数据文件infile seer9 lrecl=362;:说明每个数据行的固定长度是362个字符input @ 1 PUBCSNUM $char8. ...:这是按固定位置/宽度读取每个变量,@ X表示变量起始位置,$charN.表示这是长度为N的字符型变量
R里处理固定宽度文本文件最常用的是基础包的read.fwf,或者tidyverse生态的readr::read_fwf(速度更快),下面给你具体的转换步骤和代码:
步骤1:获取所有SEER数据文件的路径
SAS里的通配符*.TXT在R里可以用list.files实现:
# 获取目标目录下所有TXT文件的完整路径 seer_files <- list.files("./yr1973_2015.seer9", pattern = "\\.TXT$", full.names = TRUE)
步骤2:整理变量的宽度、名称和类型
你需要把SAS脚本里的每个变量定义转换成R能识别的格式,比如你给出的几个变量对应关系如下:
| SAS定义 | 变量名 | 宽度 | 类型 |
|---|---|---|---|
@ 1 PUBCSNUM $char8. | PUBCSNUM | 8 | 字符型 |
@ 9 REG $char10. | REG | 10 | 字符型 |
@ 19 MAR_STAT $char1. | MAR_STAT | 1 | 字符型 |
@ 20 RACE1V $char2. | RACE1V | 2 | 字符型 |
@ 23 NHIADE $char1. | NHIADE | 1 | 字符型 |
@ 24 SEX $char1. | SEX | 1 | 字符型 |
把这些整理成R的参数,注意所有变量的宽度总和必须等于362(对应SAS里的lrecl=362),后续你需要把SAS脚本里剩下的变量都补充进来:
# 定义变量规格:列名、宽度、类型 variable_specs <- list( names = c("PUBCSNUM", "REG", "MAR_STAT", "RACE1V", "NHIADE", "SEX"), widths = c(8, 10, 1, 2, 1, 1), # 继续添加剩余变量的宽度,总和要=362 col_classes = c("character", "character", "character", "character", "character", "character") )
步骤3:批量读取并合并所有文件
方法1:用基础包的read.fwf
# 需要批量合并文件的话,用purrr包的map_dfr(先安装:install.packages("purrr")) library(purrr) seer_data <- map_dfr(seer_files, function(file) { read.fwf( file = file, widths = variable_specs$widths, col.names = variable_specs$names, colClasses = variable_specs$col_classes, lrecl = 362, # 匹配SAS的行长度设置 encoding = "ASCII", # SEER数据是ASCII编码,避免乱码 stringsAsFactors = FALSE # 不要自动把字符转成因子 ) })
方法2:用tidyverse的readr::read_fwf(推荐,速度更快)
# 先安装readr:install.packages("readr") library(readr) library(purrr) seer_data <- map_dfr(seer_files, function(file) { read_fwf( file = file, col_positions = fwf_widths(variable_specs$widths, variable_specs$names), col_types = strrep("c", length(variable_specs$names)), # 字符型用"c",数值型改成"d" locale = locale(encoding = "ASCII") ) })
关键注意事项
- 一定要检查所有变量的宽度总和是否等于362,否则读取会出现错位或者报错
- 如果某些变量是数值型(比如诊断年份、年龄等),记得把
col_classes里对应的位置改成"numeric"(或者在read_fwf里把对应的"c"改成"d") - 如果遇到读取错误,先检查文件路径是否正确,或者行长度是否有异常(比如是否有换行符问题)
- SEER数据有时候会有特殊的编码情况,如果ASCII编码不行,可以试试
encoding = "latin1"
内容的提问来源于stack exchange,提问作者TimF
相关产品推荐
相关产品推荐

