2015-07-22 73 views
2

我试图从网站中提取值。提取的值看起来像这样。将字符转换为具有固定列数的数据帧或矩阵

"3000  ----  ----  ----  ----  '1 UNCH      '1"       
"4600  ----  ----  ----  ----  '1 UNCH      '1"       
"4800  ----  ----  ----  ----  '1 UNCH      '1"       
"5000  ----  ----  ----  ----  '1 UNCH      '1      300" 
"5200  ----  ----  ----  ----  '1 UNCH      '1"       
"5400  ----  ----  ----  ----  '1 UNCH      '1"       
"5600  ----  ----  ----  ----  '1 UNCH      '1      10" 
"5800  ----  ----  ----  ----  '1 UNCH      '1      1" 
"6000  ----  ----  ----  ----  '1 UNCH      '1     5461" 
"6200  ----  ----  ----  ----  '1 UNCH      '1      54" 
"6400  ----  ----  ----  ----  '1 UNCH      '1     2009" 
"6600  ----  ----  ----  ----  '1 UNCH      '1      124" 
"6800  ----  ----  ----  ----  '1 UNCH      '1      410" 
"7000  ----  ----  ----  ----  '1  -'1      '2     10704" 
"7200  ----  ----  '2A  ----  '2  -'1      '3     9927" 
"7400  ----  ----  ----  ----  '3 UNCH      '3     7869" 
"7600  ----  ----  ----  ----  '4 UNCH      '4   30  13596" 
"7800  ----  ----  ----  ----  '5  -'1      '6   109  16030" 
"8000   '7  '7  '7  '7  '7  -'1   467  1'0   731  26912" 
"8200  1'4  1'4  1'3  ----  1'2  -'2   119  1'4   222  11030" 
"8400  2'2  2'2  2'0  2'0  1'7  -'4   426  2'3   172  15743" 
"8600  3'1  3'3  2'7  3'0A  3'0  -'4   66  3'4   330  18964" 

有一些行的列值较少。我想创建一个11列的数据框,空白值应保持空白。当我尝试根据空间拆分值时,具有较少列值的行会重叠并重复。请找到我尝试过的代码。

cc=gsub("\\s+"," ",df) 
    cc=data.frame(cc) 
    cc = data.frame(do.call('rbind', strsplit(as.character(cc),' ',fixed=TRUE))) 
+0

任何你不能尝试使用'read.table()'的原因吗? –

+0

你为什么要把空间放出来?看起来''srsplit''可能更有意义'\\ s +' –

+0

我在后面的步骤中将其拆分。我想用一个空格替换所有空格,然后根据单个空格拆分值 –

回答

3

更新,原来的问题已经改变。

它看起来像你的数据是固定宽度的格式。您可以使用?read.fwf,但它的使用取决于数据源的可靠性。如果您从数据中获取数据的地方有一个关于数据总是如何格式化的规范(例如“11列,每列宽度为10个字符”),这将有所帮助。

# pad out each line to the same length 
maxlen <- max(sapply(df, nchar)) # it's 110 for your data, it seems 
df <- sprintf(paste0("%-", maxlen, "s"), df) 
read.fwf(textConnection(df), 
     widths=c(4, 11, 10, 10, 11, 9, 8, 12, 11, 12, 12)) 

我选择的宽度适合您提供的数据;你将不得不根据你的期望为自己确定合理的价值。


您可以使用索引将NAs放入空白位置,例如, (1:9)[1:11]将选择前9个元素(即1:9),然后在两端放置两个NA,以将其填充到11个元素长。

# assuming df is such that df[1] is the first line, df[2] is the second etc 
tmp <- strsplit(df, '\\s+') 
ncols <- max(sapply(tmp, length)) # could do max(lengths(tmp)) if you have a new 
            # enough R. Or if you already know there are 
            # at most 9 columns just set it to 9 directly 
cc <- do.call('rbind', lapply(tmp, '[', i=seq_len(ncols))) 
cc <- data.frame(cc) 
+0

试过这看起来不符合我的要求。谢谢你的帮助。如果第一行的值之间有一些空格,则移动到前一列 –

+0

有些情况下我需要将NA放在中间的列中。 –

+0

那么,你原来的问题和可重复的例子并没有反映出这一点,所以我不会介意阅读它。我会看看你更新的问题。 –

0

您可以尝试在列中使用恒定距离,每列包含字符start:end。如果最后缺少列,则NA将填充到列中。 变量“行”包含提取文件的一行。

start <- c(1,6,17, 27,37,47,57,65,77,88,100) 
end <- c(5,16,26,36,46,56,64,76,87,99,110) 

columns <- list()  
for(j in 1:length(start)){ 
    if(start[j] <= nchar(line)){ 
     columns[[j]] <- substr(line, start[j],end[j]) 
    } 
    else{ 
     y[[j]] <- NA 
    }  
}