R 读取具有隐藏字符、可变行长和空格的水平格式数据,以表示缺失的观测值
我收到了一个我从未见过的格式的数据文件,即使昨天我问了一个关于堆栈溢出的问题,也很难将数据读入SAS。今天,我能够使用下面的代码将示例数据集读入R。尽管R代码一点效率都没有。有更好的办法吗 当我在记事本中打开数据文件时,当数据达到记事本允许的单个行中的最大字符数时,数据似乎在一个长行中,该长行会卷回记事本窗口的左侧。在记事本中打开文件时,可能有10000行真实数据。其中一行中的数据与其上方或下方行中的数据不对齐 以下是数据如何显示在记事本中的示例: 以下是gVim 7.4中如何显示这些相同数据的示例: 如果我在gVim中使用:set list,我会在每一行的末尾看到一个蓝色的$,这大概就是gVim将数据与列对齐的方式 下面是我用来读取数据和创建数据帧的R代码: 上面的R代码似乎太复杂了。然而,用空白字符空间来表示缺失的观察值和可变的行长度似乎并不容易克服R 读取具有隐藏字符、可变行长和空格的水平格式数据,以表示缺失的观测值,r,R,我收到了一个我从未见过的格式的数据文件,即使昨天我问了一个关于堆栈溢出的问题,也很难将数据读入SAS。今天,我能够使用下面的代码将示例数据集读入R。尽管R代码一点效率都没有。有更好的办法吗 当我在记事本中打开数据文件时,当数据达到记事本允许的单个行中的最大字符数时,数据似乎在一个长行中,该长行会卷回记事本窗口的左侧。在记事本中打开文件时,可能有10000行真实数据。其中一行中的数据与其上方或下方行中的数据不对齐 以下是数据如何显示在记事本中的示例: 以下是gVim 7.4中如何显示这些相同数据的
感谢您的建议。以下是基于Thomas评论的解决方案:
setwd('C:/Users/markm/simple SAS programs/')
my.data3 <- read.fwf('C:/Users/markm/simple SAS programs/fake_horizontal_data_with_end_of_line_characters.txt',
widths=c(5, 10, 9, 8, 7, 5, 5, 9, 6, 10, 3, 7, 5),
colClasses = c('character', 'character', 'numeric', 'numeric', 'numeric',
'numeric', 'numeric', 'numeric', 'numeric', 'numeric',
'character', 'numeric', 'character'))
my.data3
> my.data3
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13
1 MMM 0 0 1 NA 1 1093 0 0 3 NA Y2 NA <NA>
2 MMM 0 0 1 NA 1 1284 0 NA 3 200 AN NA <NA>
3 MMM 0 0 1 NA 1 1375 4 0 0 0 <NA> NA <NA>
4 DDD 0 0 1 NA 1 1465 0 0 4 0 Y 5 <NA>
5 MDK 0 0 1 NA 1 1555 NA NA NA NA <NA> NA <NA>
6 AAB ZZ000000 5 14 NA 1234 NA 0 NA 0 B0 NA <NA>
7 AAB ZZ000000 5 14 NA 2234 2 0 NA 0 <NA> NA <NA>
8 AAB ZZ000000 5 14 NA 123 2 0 2 0 <NA> NA <NA>
9 AAA ZZ000000 5 14 NA 1234 2 0 2 0 OU NA <NA>
10 AAB 302842 5 14 NA 2222 2 0 NA 0 E4 NA A
11 EEE 123456 5 14 NA 2345 NA NA NA 0 G9 NA <NA>
12 BBB SS234567 5 14 NA 9999 3 0 NA 0 <NA> NA <NA>
13 <NA> <NA> NA NA NA NA NA NA NA NA <NA> NA <NA>
如果我想删除空白,我仍然需要修剪字符变量
编辑
这似乎会去除前导和尾随的空白:
setwd('C:/Users/markm/simple SAS programs/')
my.data3 <- read.fwf('C:/Users/markm/simple SAS programs/fake_horizontal_data_with_end_of_line_characters.txt',
widths=c(5, 10, 9, 8, 7, 5, 5, 9, 6, 10, 3, 7, 5),
colClasses = c('character', 'character', 'numeric', 'numeric', 'numeric',
'numeric', 'numeric', 'numeric', 'numeric', 'numeric',
'character', 'numeric', 'character'), strip.white = TRUE)
my.data3
> my.data3
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13
1 MMM 0 0 1 NA 1 1093 0 0 3 NA Y2 NA <NA>
2 MMM 0 0 1 NA 1 1284 0 NA 3 200 AN NA <NA>
3 MMM 0 0 1 NA 1 1375 4 0 0 0 <NA> NA <NA>
4 DDD 0 0 1 NA 1 1465 0 0 4 0 Y 5 <NA>
5 MDK 0 0 1 NA 1 1555 NA NA NA NA <NA> NA <NA>
6 AAB ZZ000000 5 14 NA 1234 NA 0 NA 0 B0 NA <NA>
7 AAB ZZ000000 5 14 NA 2234 2 0 NA 0 <NA> NA <NA>
8 AAB ZZ000000 5 14 NA 123 2 0 2 0 <NA> NA <NA>
9 AAA ZZ000000 5 14 NA 1234 2 0 2 0 OU NA <NA>
10 AAB 302842 5 14 NA 2222 2 0 NA 0 E4 NA A
11 EEE 123456 5 14 NA 2345 NA NA NA 0 G9 NA <NA>
12 BBB SS234567 5 14 NA 9999 3 0 NA 0 <NA> NA <NA>
13 <NA> <NA> NA NA NA NA NA NA NA NA <NA> NA <NA>
你想要read.fwf。一旦指定了列宽向量,就应该很容易了。
setwd('C:/Users/markm/simple SAS programs/')
my.data <- readLines('C:/Users/markm/simple SAS programs/fake_horizontal_data_with_end_of_line_characters.txt')
my.data
var1 <- substr(my.data, 1, 5)
var2 <- substr(my.data, 6, 15)
var3 <- substr(my.data, 16, 24)
var4 <- substr(my.data, 25, 32)
var5 <- substr(my.data, 33, 39)
var6 <- substr(my.data, 40, 44)
var7 <- substr(my.data, 45, 49)
var8 <- substr(my.data, 50, 58)
var9 <- substr(my.data, 59, 64)
var10 <- substr(my.data, 65, 74)
var11 <- substr(my.data, 75, 77)
var12 <- substr(my.data, 78, 84)
var13 <- substr(my.data, 85, 89)
trim <- function (x) gsub("^\\s+|\\s+$", "", x)
var1 <- trim(var1 )
var2 <- trim(var2 )
var3 <- trim(var3 )
var4 <- trim(var4 )
var5 <- trim(var5 )
var6 <- trim(var6 )
var7 <- trim(var7 )
var8 <- trim(var8 )
var9 <- trim(var9 )
var10 <- trim(var10)
var11 <- trim(var11)
var12 <- trim(var12)
var13 <- trim(var13)
var1 <- ifelse(nchar(var1 ) == 0, 'my.null', var1 )
var2 <- ifelse(nchar(var2 ) == 0, 'my.null', var2 )
var3 <- as.numeric(var3)
var4 <- as.numeric(var4)
var5 <- as.numeric(var5)
var6 <- as.numeric(var6)
var7 <- as.numeric(var7)
var8 <- as.numeric(var8)
var9 <- as.numeric(var9)
var10 <- as.numeric(var10)
var11 <- ifelse(nchar(var11) == 0, 'my.null', var11)
var12 <- as.numeric(var12)
var13 <- ifelse(nchar(var13) == 0, 'my.null', var13)
my.data2 <- data.frame(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, stringsAsFactors = FALSE)
my.data2
var1 var2 var3 var4 var5 var6 var7 var8 var9 var10 var11 var12 var13
1 MMM 0 0 1 NA 1 1093 0 0 3 NA Y2 NA my.null
2 MMM 0 0 1 NA 1 1284 0 NA 3 200 AN NA my.null
3 MMM 0 0 1 NA 1 1375 4 0 0 0 my.null NA my.null
4 DDD 0 0 1 NA 1 1465 0 0 4 0 Y 5 my.null
5 MDK 0 0 1 NA 1 1555 NA NA NA NA my.null NA my.null
6 AAB ZZ000000 5 14 NA 1234 NA 0 NA 0 B0 NA my.null
7 AAB ZZ000000 5 14 NA 2234 2 0 NA 0 my.null NA my.null
8 AAB ZZ000000 5 14 NA 123 2 0 2 0 my.null NA my.null
9 AAA ZZ000000 5 14 NA 1234 2 0 2 0 OU NA my.null
10 AAB 302842 5 14 NA 2222 2 0 NA 0 E4 NA A
11 EEE 123456 5 14 NA 2345 NA NA NA 0 G9 NA my.null
12 BBB SS234567 5 14 NA 9999 3 0 NA 0 my.null NA my.null
13 my.null my.null NA NA NA NA NA NA NA NA my.null NA my.null
setwd('C:/Users/markm/simple SAS programs/')
my.data3 <- read.fwf('C:/Users/markm/simple SAS programs/fake_horizontal_data_with_end_of_line_characters.txt',
widths=c(5, 10, 9, 8, 7, 5, 5, 9, 6, 10, 3, 7, 5),
colClasses = c('character', 'character', 'numeric', 'numeric', 'numeric',
'numeric', 'numeric', 'numeric', 'numeric', 'numeric',
'character', 'numeric', 'character'))
my.data3
> my.data3
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13
1 MMM 0 0 1 NA 1 1093 0 0 3 NA Y2 NA <NA>
2 MMM 0 0 1 NA 1 1284 0 NA 3 200 AN NA <NA>
3 MMM 0 0 1 NA 1 1375 4 0 0 0 <NA> NA <NA>
4 DDD 0 0 1 NA 1 1465 0 0 4 0 Y 5 <NA>
5 MDK 0 0 1 NA 1 1555 NA NA NA NA <NA> NA <NA>
6 AAB ZZ000000 5 14 NA 1234 NA 0 NA 0 B0 NA <NA>
7 AAB ZZ000000 5 14 NA 2234 2 0 NA 0 <NA> NA <NA>
8 AAB ZZ000000 5 14 NA 123 2 0 2 0 <NA> NA <NA>
9 AAA ZZ000000 5 14 NA 1234 2 0 2 0 OU NA <NA>
10 AAB 302842 5 14 NA 2222 2 0 NA 0 E4 NA A
11 EEE 123456 5 14 NA 2345 NA NA NA 0 G9 NA <NA>
12 BBB SS234567 5 14 NA 9999 3 0 NA 0 <NA> NA <NA>
13 <NA> <NA> NA NA NA NA NA NA NA NA <NA> NA <NA>
setwd('C:/Users/markm/simple SAS programs/')
my.data3 <- read.fwf('C:/Users/markm/simple SAS programs/fake_horizontal_data_with_end_of_line_characters.txt',
widths=c(5, 10, 9, 8, 7, 5, 5, 9, 6, 10, 3, 7, 5),
colClasses = c('character', 'character', 'numeric', 'numeric', 'numeric',
'numeric', 'numeric', 'numeric', 'numeric', 'numeric',
'character', 'numeric', 'character'), strip.white = TRUE)
my.data3
> my.data3
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13
1 MMM 0 0 1 NA 1 1093 0 0 3 NA Y2 NA <NA>
2 MMM 0 0 1 NA 1 1284 0 NA 3 200 AN NA <NA>
3 MMM 0 0 1 NA 1 1375 4 0 0 0 <NA> NA <NA>
4 DDD 0 0 1 NA 1 1465 0 0 4 0 Y 5 <NA>
5 MDK 0 0 1 NA 1 1555 NA NA NA NA <NA> NA <NA>
6 AAB ZZ000000 5 14 NA 1234 NA 0 NA 0 B0 NA <NA>
7 AAB ZZ000000 5 14 NA 2234 2 0 NA 0 <NA> NA <NA>
8 AAB ZZ000000 5 14 NA 123 2 0 2 0 <NA> NA <NA>
9 AAA ZZ000000 5 14 NA 1234 2 0 2 0 OU NA <NA>
10 AAB 302842 5 14 NA 2222 2 0 NA 0 E4 NA A
11 EEE 123456 5 14 NA 2345 NA NA NA 0 G9 NA <NA>
12 BBB SS234567 5 14 NA 9999 3 0 NA 0 <NA> NA <NA>
13 <NA> <NA> NA NA NA NA NA NA NA NA <NA> NA <NA>