我正在编写一个函数来读取具有固定宽度格式的文本文件。挑战在于事先不知道列数(它会因文件而异),因此我无法指定widths
向量与read.fwf()
一起使用。
该文件使用空格作为分隔符,一般格式为: 20个字符,4个字符,3个字符,4个字符,3个字符,...重复一对4字符(空格)3字符(空格)组合,无论需要什么数字。
该文件的示例类似于
Robert De Niro 382 +19 2504 14 346 +16 2445 18 2413 +20 2445 17
Marlon Brando 2427 +13 2495 19 2483 +14 2429 16 2438 +18 2378 20
Martin Scorsese 2501 7 317 +3 2491 1 393 +2 2462 4 394 +9
上面的示例在整个文件中有6对列。其他文件可能有多达33对列。
目前我的工作是预先手动检查每个文件以指定widths
值。关于自动化这种方法的任何建议?
答案 0 :(得分:2)
这是我在Stack Overflow上学到的一个技巧(我的片段说我是从@BenBolker学到的,但我现在无法找到链接),但只有在你的数据是格式的情况下才有效你描述:文字后跟数字。
我们说我们有以下文字:
TEXT <- c(
"Robert De Niro 382 +19 2504 14 346 +16 2445 18 2413 +20 2445 17",
"Marlon Brando 2427 +13 2495 19 2483 +14 2429 16 2438 +18 2378 20",
"Martin Scorsese 2501 7 317 +3 2491 1 393 +2 2462 4 394 +9")
我们可以使用gsub
将单词中的空格替换为另一个字符 - 例如下划线或短划线:
gsub(" +([[:alpha:]]+)", "_\\1", TEXT)
# [1] "Robert_De_Niro 382 +19 2504 14 346 +16 2445 18 2413 +20 2445 17"
# [2] "Marlon_Brando 2427 +13 2495 19 2483 +14 2429 16 2438 +18 2378 20"
# [3] "Martin_Scorsese 2501 7 317 +3 2491 1 393 +2 2462 4 394 +9"
这样我们就可以直接使用read.table
:
read.table(text = gsub(" +([[:alpha:]]+)", "_\\1", text), header = FALSE)
# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13
# 1 Robert_De_Niro 382 19 2504 14 346 16 2445 18 2413 20 2445 17
# 2 Marlon_Brando 2427 13 2495 19 2483 14 2429 16 2438 18 2378 20
# 3 Martin_Scorsese 2501 7 317 3 2491 1 393 2 2462 4 394 9
正如@BondedDust所提到的,如果你想保留&#34; +&#34;你可以指定colClasses = "character"
。在数字之前,但那么你的数字将是字符: - )
答案 1 :(得分:1)
您可以读取最大值然后进行后处理以删除所有NA的所有列:
> read.fwf(textConnection("Robert De Niro 382 +19 2504 14 346 +16 2445 18 2413 +20 2445 17
+ Marlon Brando 2427 +13 2495 19 2483 +14 2429 16 2438 +18 2378 20
+ Martin Scorsese 2501 7 317 +3 2491 1 393 +2 2462 4 394 +9"), widths=c(20, rep(c(5,4), 33) ) )
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14
1 Robert De Niro 382 19 2504 14 346 16 2445 18 2413 20 2445 17 NA
2 Marlon Brando 2427 13 2495 19 2483 14 2429 16 2438 18 2378 20 NA
3 Martin Scorsese 2501 7 317 3 2491 1 393 2 2462 4 394 9 NA
V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33
1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 V51 V52
1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
V53 V54 V55 V56 V57 V58 V59 V60 V61 V62 V63 V64 V65 V66 V67
1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
如果您需要保留&#39; +&#39; -signs,请使用colClasses。特别是跟进Ananda的贡献后,这可以作为一个单行使用更灵活的read.table()方法:
fil <- <insert-file-name-here>
read.table(text=gsub(" +([[:alpha:]]+)", "_\\1", textConnection( file(fil) ),
col.Classes=c("character", "numeric") )
colClasses将根据需要重复多次,因此例如11列文件将被读为:c(&#34;字符&#34;,&#34;数字&#34;,&#34 ;字符&#34;,&#34;数字&#34;,&#34;字符&#34;,&#34;数字&#34;,&#34;字符&#34;,&#34;数字&#34; ,&#34;字符&#34;,&#34;数字&#34;,&#34;字符&#34;)