试图弄清楚如何分解文本文件

时间:2018-08-12 22:54:01

标签: r dataframe data-manipulation

我大约20年前的一个项目中有很多文本文件(必须从软盘导入!)。原始软件使用FORTRAN并可以直接读取文件,但是我想在R中进行更有效的操作。当我将文件读取到R中时,就会得到与创建以下数据框时所得到的类似的东西:

dataset <-   
as.data.frame(c("R4 8561   200 365801HARLAN     16161616116616166116",  
              "R5 8533   100 472801WHITE      11611111111111111111",  
              "R4 8573   100 485101MCKENNA    11611161161111611161",  
              "R6 8513   200 489801HOLMES     66116111611161111161",  
              "R4 8522   200 492201DAY        11111611111111116111",  
              "R6 8548   100 500901LURTON     11116111911161111111",  
              "R5 8547   100 507322HUGHES     16611111111161116611",  
              "R4 85 3   100 518001VANDEVANTER99999911111111111111",  
              "R5 8553   100 521301LAMAR      99999911111111111111",  
              1910))  

这应以10 x 1数据帧开始。我正在拔头发,尝试执行以下操作:

(1)删除数据集的最后一行,无论数据集有多长。当我做诸如数据集<-dataset [-nrow(dataset)]之类的操作时,由于某种原因,它会将帧变成一个因素。然后

(2)将每个单元格中的所有内容放在名称之前。名称始终以21个字符开头;

(3)有了这些名称之后,我想将名称(始终长11个字符,如果需要,还包括空格)与数字(代表一系列投票)分开;

(4)一旦有了,就将数字切成单独的单元(始终为1、6或9)。该数字的长度将因文件而异。

非常感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

我强烈建议您使用read.fwf,它允许您读取具有固定列宽格式的文件。

考虑由以下lines

组成的数据
lines <-
"R4 8561   200 365801HARLAN     16161616116616166116s
R5 8533   100 472801WHITE      11611111111111111111s
R4 8573   100 485101MCKENNA    11611161161111611161s
R6 8513   200 489801HOLMES     66116111611161111161s
R4 8522   200 492201DAY        11111611111111116111s
R6 8548   100 500901LURTON     11116111911161111111s
R5 8547   100 507322HUGHES     16611111111161116611s
R4 85 3   100 518001VANDEVANTER99999911111111111111s
R5 8553   100 521301LAMAR      99999911111111111111s
1910"

然后,我们以函数参数width中指定的固定列宽格式读取数据(第一列的宽度为20,第二列的宽度为11,依此类推)。

df <- read.fwf(textConnection(lines), width = c(20, 11, 1, 6, 9))

# Remove first column and last line
df[-nrow(df), -1]
#           V2 V3     V4        V5
#1 HARLAN       1 616161 611661616
#2 WHITE        1 161111 111111111
#3 MCKENNA      1 161116 116111161
#4 HOLMES       6 611611 161116111
#5 DAY          1 111161 111111111
#6 LURTON       1 111611 191116111
#7 HUGHES       1 661111 111116111
#8 VANDEVANTER  9 999991 111111111
#9 LAMAR        9 999991 111111111

一些其他评论:

  1. read.fwffile作为其第一个参数,例如您应该使用read.fwf(filename, width = ...)
  2. 您可能要使用trimws来修剪前导/后缀空白。

答案 1 :(得分:0)

   public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name')
                ->add('sprint', SprintType::class);
    }

转换为字符:

dataset <-    data.frame(
              test = c("R4 8561   200 365801HARLAN     16161616116616166116",  
              "R5 8533   100 472801WHITE      11611111111111111111",  
              "R4 8573   100 485101MCKENNA    11611161161111611161",  
              "R6 8513   200 489801HOLMES     66116111611161111161",  
              "R4 8522   200 492201DAY        11111611111111116111",  
              "R6 8548   100 500901LURTON     11116111911161111111",  
              "R5 8547   100 507322HUGHES     16611111111161116611",  
              "R4 85 3   100 518001VANDEVANTER99999911111111111111",  
              "R5 8553   100 521301LAMAR      99999911111111111111",  
              1910))

dataset <- dataset[-nrow(dataset), ]

剥离前20个字符:

dataset$test <- as.character(dataset$test)

获取姓名:

dataset$new <- substr(dataset$test,21,100000)

获取号码:

dataset$names <- gsub("^([A-Z]+).*", "\\1", dataset$new)

关于如何将数字分成几列,应该有一个已回答的问题,请参见here

dataset$numbers <- gsub(".*?(\\d+)$", "\\1", dataset$new)

答案 2 :(得分:0)

这里是方法之一:使用文本函数:nchar-字符串中的字符数,substr-使用开始和结束字符分割字符串,strsplit-将图形分割成单独的列:

    dataset <- as.data.frame(dataset[-nrow(dataset), ],  stringsAsFactors=F)
    colnames(dataset) <- "text"
    drop20 <- function(x){substr(x, 21, nchar(x))}
    dataset <- as.data.frame(sapply(dataset, drop20), stringsAsFactors=F)
    colnames(dataset) <- "text"

    cellnamesplit <- function(x){substr(x, 1, 11)}
    cellvaluesplit <- function(x){substr(x, 12, nchar(x))}
    cellname <- as.data.frame(sapply(dataset, cellnamesplit), stringsAsFactors=F)
    cellvalue <- as.data.frame(sapply(dataset, cellvaluesplit), stringsAsFactors=F)

    splitvalues <- function(x){strsplit(x, "")}
    valcellall <- t(as.data.frame(apply(cellvalue, 1, splitvalues), stringsAsFactors=F))

    final <- cbind(cellname, valcellall)