如何在R中导入列分隔符数量不同的txt文件

1bqhqjot  于 2023-03-15  发布在  其他
关注(0)|答案(2)|浏览(178)

我在R中导入一个txt文件,带有分号“;“分隔符。
文件中有28列,几乎有800万个观察值。但是,在某些行中,分隔符的格式很差,所以在某些情况下,有26或27个分隔符,而不是28个。这导致R在遇到这些格式很差的行时停止导入。我可以调整原始文件,但有数千个观察值,使过程非常乏味。
我正在使用data.table中的fread。有什么方法可以解决这个问题吗?也许只导入分隔符数量正确的行(我该怎么做呢)?
谢谢你的帮助!
大概是这样:

col1;col2;col3;col4;col5;col6;col7;col8;col9;col10;col11;col12;col13;col14;col15;col16;col17;col18;col19;col20;col21;col22;col23;col24;col25;col26;col27;col28
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;2;0;21;22;23;24;25;26;27;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;1;7;18;19;20;21;22;23;24;25;26;27;
This is a line of text;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;
This is a;nother line of text;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;;
9nvpjoqh

9nvpjoqh1#

我建议你把每一行作为一个字符串读入,然后使用separate_wider_delim()在分号处分割每一行,这个函数可以通过指定too_few参数来处理不同的行长度:

library(tidyverse)

test <- read_lines("test.csv")

tibble(col = test[-1]) |> 
  separate_wider_delim(
    col, 
    delim = ";", 
    names_sep = "_",
    too_few = "align_start")
#> # A tibble: 7 × 29
#>   col_1     col_2 col_3 col_4 col_5 col_6 col_7 col_8 col_9 col_10 col_11 col_12
#>   <chr>     <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>  <chr>  <chr> 
#> 1 1         2     3     4     5     6     7     8     9     10     11     12    
#> 2 1         2     3     4     5     6     7     8     9     10     11     12    
#> 3 This is … 2     3     4     5     6     7     8     9     10     11     12    
#> 4 1         2     3     4     5     6     7     8     9     10     11     12    
#> 5 1         2     3     4     5     6     7     8     9     10     11     12    
#> 6 This is a noth… 2     3     4     5     6     7     8     9      10     11    
#> 7 1         2     3     4     5     6     7     8     9     10     11     12    
#> # … with 17 more variables: col_13 <chr>, col_14 <chr>, col_15 <chr>,
#> #   col_16 <chr>, col_17 <chr>, col_18 <chr>, col_19 <chr>, col_20 <chr>,
#> #   col_21 <chr>, col_22 <chr>, col_23 <chr>, col_24 <chr>, col_25 <chr>,
#> #   col_26 <chr>, col_27 <chr>, col_28 <chr>, col_29 <chr>

创建于2023年3月12日,使用reprex v2.0.2
末尾的分号被解释为包含空字符串的另一列。要将它们也转换为NA,请将mutate(across(everything(), ~na_if(.x, "")))行添加到管道中。

vxf3dgd4

vxf3dgd42#

我建议使用readLines函数,以后根据您的策略逐行处理。您可以使用stringi::stri_count("a;b;c", fixed = ";")函数识别数字;。
例如,当您想跳过没有28的行时;。

# stringi dependency
df_lines <- readLines("PATH.txt")
df_lines_h <- df_lines[1]
df_lines_h_split <- strsplit(df_lines_h, ";")[[1]]
df_lines_body <- df_lines[-1]
res <- list()
for (line in df_lines_body) {
  n_semi <- stringi::stri_count(line, fixed = ";")
  if (n_semi == 28) {
    line_split <- strsplit(line, ";")[[1]]
    res <- append(res, list(line_split))
  }
}
final <- do.call(rbind, append(list(df_lines_h_split), res))

相关问题