【发布时间】:2018-03-17 15:12:28
【问题描述】:
我有一个格式如下的原始文本文件:
发布版本:20150514(2015 年 5 月 14 日)
================================================ =========================版本
研究变量:发布版本号
问题: --------- 累积数据文件的版本
注意事项: ------ 此变量在数据中显示为: ANES_cdf_VERSION:YYYY-mmm-DD 其中 mmm 是标准的 3 字符月份缩写(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)。
类型: ----- 字符 1
================================================ ========================== VCF0004
学习变量:学习年份
问题: --------- 学习年份(4 位数)
类型: ----- 数字 12 月 0-1 日
================================================ ======================= VCF0006 ... 等等
观察以“=”行为界,每个观察都有一定数量的变量(可能不会全部呈现)
我正在尝试从中创建一个数据表。
我创建了一个观察向量,在每个观察列中用“|”分隔。然后我用fread做一个数据表:
dt <- fread(paste(rawObs, collapse = '\n'),sep = '|',header = F, fill = T)
但是,这并不是真正的解决方案。 Fill = T 只考虑观察结束时的缺失列,而不是介于两者之间:
在我们的例子中应该是:
id | study_var | question | notes | type
version | s1 | q1 | notes1 | character-1
VCF0004 | s2 | q2 | NA | numeric
但是 R 将它创建为
id | study_var | question | notes | type
version | s1 | q1 | notes1 | character-1
VCF0004 | s2 | q2 | numeric | NA
第二个观察的类型向左移动。作为一种解决方案,我正在考虑确定每个观察值中缺少的列,并在输入文件中显式插入 NA,使用找到的最大变量数,但对于大文件可能会很慢。
感谢您的帮助。任何 cmets 表示赞赏。 这是所有代码:
library(magrittr)
library(data.table)
path <- 'Downloads/anes_timeseries_cdf_codebook_var.txt'
raw_data <- readLines(path)
head(raw_data)
#remove empty lines
raw_data <- raw_data[raw_data != ""]
#remove header
raw_data <- raw_data[-c(1,2)]
data_entries_index <- grep('^=+', raw_data)+1
#add end position of the last observation
data_entries_index <- c(data_entries_index, length(raw_data))
#opening file shows editor couldn't read two characters - we can ignore it though
data_entries_index
parseRawObservation <- function(singleRawObs, VariableIndex){
count=length(VariableIndex)-1
for (i in 1:count){
start = VariableIndex[i]+2
end = VariableIndex[i+1]-1
varValue <- paste(singleRawObs[start:end],collapse = ' ')
if (i==1)
obsSpaced <- varValue
else
obsSpaced <- paste(obsSpaced,varValue, sep = '|')
}
obsSpaced
}
#create a vector of raw observations
numObs <- length(data_entries_index)
count=numObs-1
rawObs=vector()
for (i in 1:count) {
start <- data_entries_index[i]
end <- data_entries_index[i+1]-2
singleRawObs <-raw_data[start:end]
VariableIndex <- grep("^-+",singleRawObs)-1
#add end of the last variable index
VariableIndex <- c(VariableIndex, length(singleRawObs)+1)
rawObs[i] <- parseRawObservation(singleRawObs,VariableIndex)
#add first two columns separately as they do not have dashes at the next line
rawObs[i] <- paste(singleRawObs[1], singleRawObs[2], rawObs[i], sep = '|')
}
#determine max number of fields
numOfCol <- max(sapply(rawObs, FUN = function(x) length(strsplit(x,'|')[[1]])))
which.max(sapply(rawObs, FUN = function(x) length(strsplit(x,'|')[[1]])))
dt <- fread(textConnection(rawObs),sep = '|',header = F)
dt <- fread(paste(rawObs[1:2], collapse = '\n'),sep = '|',header = F, fill = T)
rawObs[653]
【问题讨论】: