Так что другие комментарии и ответы указывают на большую часть этого, но вот более полный ответ для вашей конкретной проблемы. Я слышал о многих людях, борющихся с этими файлами ASCII (включая многие связанные, но не очень простые пакеты), и я хотел ответить на них всем, кто ищет.
Файлы фиксированной ширины
Эти файлы SEER "ASCII" на самом деле являются текстовыми файлами фиксированной ширины (ASCII - это стандарт кодирования, а не формат файла). Это означает, что нет символа разделителя (например, "," или "\ t"), который разделяет поля (в .csv или .tsv).
Вместо этого каждое поле определяется начальной и конечной позицией в строке (иногда начальной позицией и шириной / длиной поля). Вот что мы видим в файле .sas, который вы суммируете:
input
@ 1 PUBCSNUM $char8. /* Patient ID */
@ 9 REG $char10. /* SEER registry */
...
Что это значит?
- первое поле идентификатора пациента начинается с позиции 1 и имеет длину 8 (от $ char8, аналогично точности в схемах SQL и т. Д.), Что означает, что оно заканчивается в позиции 8 .
- второе поле, идентификатор реестра SEER, начинается с позиции 9 (1 + 8 от предыдущего поля) и имеет длину 10 (снова от $ char10), что означает заканчивается в позиции 18 .
- и т.д..
Где число @
постоянно увеличивается, поэтому поля не перекрываются.
Чтение файлов фиксированной ширины
Я считаю, что функция readr::read_fwf()
приятна и проста, в основном потому, что она имеет несколько вспомогательных функций, а именно fwf_positions()
, которые сообщают ей, как определять каждое поле по началу и концу (или по ширине с fwf_widths()
).
Итак, чтобы прочитать только эти два поля из файла, мы можем сделать:
read_fwf(<file>, fwf_positions(start=c(1, 9), end=c(8, 18), col_names=c("patient_id", "registry_id")))
Где col_names только для переименования столбцов.
Вспомогательный скрипт.
Я боролся с этим прежде, поэтому я на самом деле написал некоторый код , который читает этот файл .sas и извлекает начальные позиции, ширину, имена столбцов и описания.
Вот и все, просто замените имя файла:
## Script to read the SEER file dictionary and use it to read SEER ASCII data files.
library(tidyverse)
library(stringr)
#### Reading the file dictionary ----
## https://seer.cancer.gov/manuals/read.seer.research.nov2017.sas
sas.raw <- read_lines("https://seer.cancer.gov/manuals/read.seer.research.nov2017.sas")
sas.df <- tibble(raw = sas.raw) %>%
## remove first few rows by insisting an @ that defines the start index of that field
filter(str_detect(raw, "@")) %>%
## extract out the start, width and column name+description fields
mutate(start = str_replace(str_extract(raw, "@ [[:digit:]]{1,3}"), "@ ", ""),
width = str_replace(str_extract(raw, "\\$char[[:digit:]]{1,2}"), "\\$char", ""),
col_name = str_extract(raw, "[[:upper:]]+[[:upper:][:digit:][:punct:]]+"),
col_desc = str_trim(str_replace(str_replace(str_extract(raw, "\\/\\*.+\\*\\/"), "\\/\\*", ""), "\\*\\/", "" )) ) %>%
## coerce to integers
mutate_at(vars(start, width), funs(as.integer)) %>%
## calculate the end position
mutate(end = start + width - 1)
column_mapping <- sas.df %>%
select(col_name, col_desc)
#### read the file with the start+end positions----
## CHANGE THIS LINE
file_path = "data/test_COLRECT.txt"
## read the file with the fixed width positions
data.df <- read_fwf(file_path,
fwf_positions(sas.df$start, sas.df$end, sas.df$col_name))
## result is a tibble
Надеюсь, это поможет!