导入带有大小写不变的 na.strings 参数的 CSV

Import CSV with case-invariant na.strings argument

提问人:jpsmith 提问时间:11/10/2023 最后编辑:jpsmith 更新时间:11/11/2023 访问量:127

问:

我尝试导入一个 CSV 文件,其中包含不一致的大小写变体以指示缺少数据,例如:

read.csv(
  text = "A,B,C
  1,Not indicated, NOT indicated
  4,abc,not indicated
  NOT INDICATED, def, noT InDiCated")

#                 A             B              C
# 1               1 Not indicated  NOT indicated
# 2               4           abc  not indicated
# 3   NOT INDICATED           def  noT InDiCated

我正在尝试将它们导入到函数(或来自另一个包的类似函数),忽略大小写。我想要的输出是:NAread.csv()

#      A    B    C
# 1    1   NA   NA
# 2    4  abc   NA
# 3   NA  def   NA

该命令接受字符串的字符向量来替换 ,但大小写变体最初是未知的,并且有太多的排列,因此不切实际。read.csv()na.stringNA

有没有办法使用正则表达式或其他替代方法来导入所有大小写变体,而无需指定每个案例变体?在这种特定情况下,重要的是在读取数据时(即,在或类似)中实现这一点,而不是在额外的步骤中(即,读入数据,然后使用其他代码进行清理,(即,如此处)。NAread.csv

我试过:

read.csv(
  text = "A,B,C
  1,Not indicated, NOT indicated
  4,abc,not indicated
  NOT INDICATED, def, noT InDiCated" 
  na.strings = "(?i)not (?i)indicated") ## nothing is replaced

read.csv(
  text = "A,B,C
  1,Not indicated, NOT indicated
  4,abc,not indicated
  NOT INDICATED, def, noT InDiCated", 
  na.strings = c("not indicated"), 
  ignore.case = TRUE) # Returns error/unused argument

read.csv(
  text = "A,B,C
  1,Not indicated, NOT indicated
  4,abc,not indicated
  NOT INDICATED, def, noT InDiCated",
  na.strings = stringr::regex("not indicated", ignore_case = TRUE)) # does not return NA for any of the variants

我尝试过与 和 类似的方法,但它们都没有返回所需的输出(返回类似于上面的输出/错误)。不幸的是,现有的 SO 问题都没有解决特定问题(即,使 csv 数据导入不区分大小写或在 R 中搜索列表不区分大小写data.table::freadreadr::read_csv)

r csv

评论


答:

4赞 zx8754 11/10/2023 #1

在面包内更换 - 使用:sed

data.table::fread("sed 's/not indicated/NA/gI' tmp.csv")
#     A  B  C
# 1:  1 NA NA
# 2:  4  5 NA
# 3: NA  8 NA

检查操作系统,然后运行等效的“sed”命令:

评论

0赞 Axeman 11/10/2023
这太棒了!但我想不能移植到 Windows?
0赞 zx8754 11/10/2023
@Axeman true,那么您必须找到 sed 的 PowerShell 替代品。在恐惧之前可以进行简单的检查,找出操作系统,然后运行相关命令。
0赞 Friede 11/10/2023
@zx8754,出于兴趣,我想问一下这样的检查会是什么样子。基于?.Platform$OS.type
1赞 zx8754 11/11/2023
@Friede是的,这就是我的想法,有很多方法,编辑,请参阅链接的帖子。
5赞 thelatemail 11/10/2023 #2

澄清后将评论升级为答案:

您可以导入原始文本,应用正则表达式替换,然后将其传递给 .这将推迟对列类型等的猜测,直到某些字符串被剥离之后。read.csv

这并不完全是你想要的,但我认为按照所要求的方式这是不可能的。scan()na.strings=

一个(不是很健壮的)尝试,可以作为一个起点:

read.csv(
   text=gsub("not indicated", "NA", 
          readChar("test.csv", nchars=file.size("test.csv"), useBytes=TRUE),
          ignore.case=TRUE), 
   na.strings="NA", strip.white=TRUE
)

##   A  B  C
##1  1 NA NA
##2  4  5 NA
##3 NA  8 NA