首页 > 解决方案 > 强制 readr 中的 read_delim 将多个 " 和 \ 作为列字符串的一部分

问题描述

给定一个;分隔文件的结构:

colA; colB; colC
1;A; 10
2;B; 11     
3;C"; 12
4;D""; 15
5;"F";20
6;K"""; 21
7;""M";22
8; \""O;23

我想确保colB始终将其作为字符串逐字导入。特别是,我想保留所有值,包括""M"\""O

试图

我目前正在尝试:

require(readr)
tst_dta <- read_delim(
  file = "test_file.csv",
  escape_double = FALSE,
  delim = ";",
  col_types = cols(
    colA = col_integer(),
    colB = col_character(),
    colC = col_integer()
  )
)

但这会返回:

> tst_dta
# A tibble: 8 x 3
   colA colB        colC
  <int> <chr>      <int>
1     1 A             10
2     2 B             NA
3     3 "C\""         12
4     4 "D\"\""       15
5     5 F             20
6     6 "K\"\"\""     21
7     7 "\"\"M\""     22
8     8 " \\\"\"O"    23

期望的结果

预期结果应反映:

    colA colB  colC
   <int> <chr> <int>
    1     A     10
    2     B     11     
    3     C"    12
    4     D""   15
    5    "F"    20
    6     K"""  21
    7   ""M"    22
    8  \""O     23

其他要点:


更新

根据评论,更多示例:

是:

colA; colB; colC
1; text \" text; 2

应该:

colA;colB;colC
1;text text;2

是:

colA; colB; colC
1; text \;" text; 2

应该:

colA;colB;colC
1;text text;2

是:

colA; colB; colC
1; [non-ASCII] text something \;" text; 2

应该:

colA;colB;colC
1;text something;2

标签: rcsvimportspecial-charactersreadr

解决方案


如果您需要使用readr-functions,请查看它的参数列表,看看它是否与quotein 的参数等效read.table(允许简单访问:

 read.table(text=txt, header=TRUE, quote="", sep=";")
  colA colB colC
1    1    A   10
2    2    B   11
3    3   C"   12
4    4  D""   15
5    5  "F"   20
6    6 K"""   21
7    7 ""M"   22
8    8  ""O   23

似乎它应该成功,因为它是readr::read_delim. 两种情况下的默认值都是"\""单双引号。将其设置为空字符 ( ""):

用法

read_delim(file, delim, quote = "\"", escape_backslash = FALSE,
  escape_double = TRUE, col_names = TRUE, col_types = NULL,
  locale = default_locale(), na = c("", "NA"), quoted_na = TRUE,
  comment = "", trim_ws = FALSE, skip = 0, n_max = Inf,
  guess_max = min(1000, n_max), progress = show_progress())

这是结果的打印表示。我会注意到这种打印表示似乎有点不规则。当字符值嵌入了双引号时,它们才用双引号括起来,即\". 另一方面,这些列字符,与 read.table 中的默认设置相比是一个很好的变化,它为您提供了因子列:

read_delim(file=txt,  quote="", delim=";")
# A tibble: 8 x 3
   colA ` colB`   ` colC`   
  <int> <chr>     <chr>     
1     1 A         " 10"     
2     2 B         " 11     "
3     3 "C\""     " 12"     
4     4 "D\"\""   " 15"     
5     5 "\"F\""   20        
6     6 "K\"\"\"" " 21"     
7     7 "\"\"M\"" 22        
8     8 " \"\"O"  23 

特此警告您,使用此选项read_delim确实意味着不会修剪列名和值以删除空格。一切都是如此,即使是character原本会以character. 注意第二列的名称。这不会发生在read.table

read_delim(file=txt,  quote="", delim=";")$` colB` == 
         read.table(text=txt, header=TRUE, quote="", sep=";")$colB
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

gsub如果您想要删除前导或尾随空格,则需要进一步处理。rm_non_ascii在 pkg {qdapRegex} 可以删除非 ASCII 字符


推荐阅读