Rev 5664 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
### This file is part of the 'foreign' package for R.### R/read.epiinfo.R### (c) 2002-4 Thomas Lumley### Patches (c) 2002 Mark Myatt# This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## A copy of the GNU General Public License is available at# http://www.r-project.org/Licenses/read.epiinfo <- function (file, read.deleted = FALSE,guess.broken.dates = FALSE, thisyear = NULL,lower.case.names = FALSE){if (is.character(file)) {file <- file(file, "rt")on.exit(close(file))}if (!inherits(file, "connection"))stop("argument 'file' must be a character string or connection")if (!isOpen(file)) {open(file, "rt")on.exit(close(file))}line <- readLines(file, 1L, ok = TRUE)headerlength <- na.omit(sapply(strsplit(line, " ")[[1L]], as.numeric))[1L]if (headerlength <= 0L)stop("file has zero or fewer variables: probably not an EpiInfo file")headerlines <- readLines(file, n = headerlength)pushBack(headerlines, file)comments <- vapply(headerlines, function(s) substring(s, 46L, 46L + 80L), "")## Added comment = "" to fix '#' as entrychar being read as a comment#header <- scan(file, nlines = headerlength,what = list(name = "", x = 0, y = 0, color = 0, x1 = 0,y1 = 0, type = 0, len = 0, color = 0),flush = TRUE, quiet = TRUE, comment.char = "")header <- as.data.frame(lapply(header, I))header$start <- cumsum(c(1L, header$len))[1L:headerlength]header$stop <- cumsum(header$len)multiline <- ceiling(max(header$stop) / 78L)really.variables <- header$len != 0header <- header[really.variables, ]entrychar <- substr(header$name, 1L, 1L)if (all(entrychar %in% c("#", "_")))header$name <- substr(header$name, 2L, 12L)comments <- comments[really.variables]## Added support for EpiData introduced field types:## 12 Automatic ID number fields (treated as numeric)# 16 European (i.e. dd/mm/yyyy) format automatic date# 17 SOUNDEX field#numbers <- (header$len > 0L) & ((header$type %in% c(0L, 6L, 12L)) | (header$type > 12L)) & !(header$type %in% c(16L, 17L))datalines <- scan(file, what = "", sep = "\n", quote = "", quiet = TRUE, blank.lines.skip = TRUE, comment.char = "")## Added check for empty file#if (length(datalines) == 0L)stop("no records in file")if (length(datalines)%%multiline)warning("wrong number of records")datalines <- matrix(datalines, nrow = multiline)if (multiline > 1L)datalines[-multiline, ] <- substr(datalines[-multiline, ], 1L, 78L)datalines <- apply(datalines, 2L, paste, collapse = "")deleted <- substr(datalines, nchar(datalines), nchar(datalines)) == "?"nvars <- NROW(header)data <- as.data.frame(lapply(1L:nvars, function(i) I(substring(datalines, header$start[i], header$stop[i]))))names(data) <- header$namenames(comments) <- header$nameif (is.na(read.deleted))data[deleted, ] <- NAelse if (!read.deleted)data <- data[!deleted, ]if (guess.broken.dates && is.null(thisyear))thisyear <- format(Sys.time(), format = "%Y")## Added support for field types:## 10 US (i.e. mm/dd/yyyy) format field (EpiInfo)# 12 Automatic ID number (treated as numeric)# 16 European (i.e. dd/mm/yyyy) format automatic date (EpiData)# 17 SOUNDEX field (EpiData)#for (i in 1L:nvars) {if (numbers[i])data[[i]] <- as.numeric(data[[i]])else if (header$type[i] == 5L)data[[i]] <- ifelse(data[[i]] %in% c("Y", "N"), data[[i]] == "Y", NA)else if (header$type[i] %in% c(11L, 16L) && header$len[i] == 5L && guess.broken.dates)data[[i]] <- as.Date(strptime(paste(data[[i]], thisyear, sep = "/"), format = "%d/%m/%Y"))else if (header$type[i] %in% c(11L, 16L) && header$len[i] == 8L && guess.broken.dates)data[[i]] <- as.Date(strptime(data[[i]], format = "%d/%m/%y"))else if (header$type[i] %in% c(11L, 16L) && header$len[i] == 10L)data[[i]] <- as.Date(strptime(data[[i]], format = "%d/%m/%Y"))else if (header$type[i] %in% c(2L, 10L) && header$len[i] == 5L && guess.broken.dates)data[[i]] <- as.Date(strptime(paste(data[[i]], thisyear, sep = "/"), format = "%m/%d/%Y"))else if (header$type[i] %in% c(2L, 10L) && header$len[i] == 8L && guess.broken.dates)data[[i]] <- as.Date(strptime(data[[i]], format = "%m/%d/%y"))else if (header$type[i] %in% c(2L, 10L) && header$len[i] == 10L)data[[i]] <- as.Date(strptime(data[[i]], format = "%m/%d/%Y"))## SOUNDEX (type 17) fields#else if (header$type[i] == 17L) {data[[i]][substr(data[[i]], 1L, 1L) == " "] <- NAdata[[i]] <- substr(data[[i]], 1L, 5L)}else {blanks <- grep("^[[:blank:]]*$", data[[i]])data[[i]][blanks] <- NA}}if (!is.na(read.deleted) && read.deleted)attr(data, "deleted") <- deletedattr(data, "prompts") <- comments## Added parameter and code to specify lower case variable names#if (lower.case.names)names(data) <- tolower(names(data))data}